From 32e3a4e74f4bc7d9d55c351d0367133bd9dd3871 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 9 Sep 2025 22:30:29 +0200 Subject: [PATCH] impr: Move items from pattern editor console area to more appropriate places --- .../content/views/view_pattern_data.hpp | 8 + .../content/views/view_pattern_editor.hpp | 15 +- plugins/builtin/romfs/lang/de_DE.json | 2 +- plugins/builtin/romfs/lang/en_US.json | 5 +- plugins/builtin/romfs/lang/es_ES.json | 2 +- plugins/builtin/romfs/lang/fr_FR.json | 4 +- plugins/builtin/romfs/lang/hu_HU.json | 2 +- plugins/builtin/romfs/lang/it_IT.json | 2 +- plugins/builtin/romfs/lang/ja_JP.json | 2 +- plugins/builtin/romfs/lang/ko_KR.json | 2 +- plugins/builtin/romfs/lang/pl_PL.json | 4 +- plugins/builtin/romfs/lang/pt_BR.json | 2 +- plugins/builtin/romfs/lang/ru_RU.json | 2 +- plugins/builtin/romfs/lang/zh_CN.json | 4 +- plugins/builtin/romfs/lang/zh_TW.json | 2 +- .../content/views/view_pattern_data.cpp | 233 ++++++++++++++---- .../content/views/view_pattern_editor.cpp | 217 ++++++---------- 17 files changed, 298 insertions(+), 210 deletions(-) diff --git a/plugins/builtin/include/content/views/view_pattern_data.hpp b/plugins/builtin/include/content/views/view_pattern_data.hpp index fbaa9df2f..4dc4008ca 100644 --- a/plugins/builtin/include/content/views/view_pattern_data.hpp +++ b/plugins/builtin/include/content/views/view_pattern_data.hpp @@ -7,6 +7,12 @@ namespace hex::plugin::builtin { + struct VirtualFile { + std::fs::path path; + std::vector data; + Region region; + }; + class ViewPatternData : public View::Window { public: ViewPatternData(); @@ -26,6 +32,8 @@ namespace hex::plugin::builtin { PerProvider>> m_patternDrawer; Region m_hoveredPatternRegion = Region::Invalid(); ui::PatternValueEditor m_patternValueEditor; + PerProvider> m_virtualFiles; + }; } \ No newline at end of file diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 091e2863b..e84ddf6a6 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -68,12 +68,6 @@ namespace hex::plugin::builtin { void setPopupWindowHeight(u32 height) { m_popupWindowHeight = height; } u32 getPopupWindowHeight() const { return m_popupWindowHeight; } - struct VirtualFile { - std::fs::path path; - std::vector data; - Region region; - }; - enum class DangerousFunctionPerms : u8 { Ask, Allow, @@ -165,13 +159,13 @@ namespace hex::plugin::builtin { PerProvider> m_lastEvaluationOutVars; PerProvider> m_patternVariables; - PerProvider> m_virtualFiles; PerProvider> m_envVarEntries; PerProvider m_analysisTask; PerProvider m_shouldAnalyze; PerProvider m_breakpointHit; + PerProvider m_debuggerActive; PerProvider> m_debuggerDrawer; std::atomic m_resetDebuggerVariables; int m_debuggerScopeIndex = 0; @@ -207,11 +201,12 @@ namespace hex::plugin::builtin { TextHighlighter m_textHighlighter = TextHighlighter(this,&this->m_editorRuntime); private: void drawConsole(ImVec2 size); - void drawEnvVars(ImVec2 size, std::list &envVars); - void drawVariableSettings(ImVec2 size, std::map &patternVariables); - void drawVirtualFiles(ImVec2 size, const std::vector &virtualFiles) const; void drawDebugger(ImVec2 size); + void drawPatternSettings(); + void drawEnvVars(std::list &envVars); + void drawVariableSettings(std::map &patternVariables); + void drawPatternTooltip(pl::ptrn::Pattern *pattern); void drawTextEditorFindReplacePopup(ui::TextEditor *textEditor); diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index 3c5ce1b32..9b9b85acd 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -899,7 +899,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "Ersetzen", "hex.builtin.view.pattern_editor.replace_hint_history": " für Historie)", "hex.builtin.view.pattern_editor.settings": "Einstellungen", - "hex.builtin.view.pattern_editor.virtual_files": "Virtuelle Dateien", + "hex.builtin.view.pattern_data.virtual_files": "Virtuelle Dateien", "hex.builtin.view.provider_settings.load_error": "Ein Fehler beim Öffnen dieses Providers ist aufgetreten!", "hex.builtin.view.provider_settings.load_error_details": "Ein Fehler ist aufgetreten während der Provider geladen wurde.\nDetails: {0}", "hex.builtin.view.provider_settings.load_popup": "Provider öffnen", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index ab27b4c1d..12f42cf21 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -983,6 +983,7 @@ "hex.builtin.view.pattern_data.section.main": "Main", "hex.builtin.view.pattern_data.section.view_raw": "View Raw Data", "hex.builtin.view.pattern_data.simplified_editor": "Simplified", + "hex.builtin.view.pattern_data.simplified_editor.no_patterns": "Mark patterns with the [[hex::editor_export]] attribute to make them appear in a simplified way here", "hex.builtin.view.pattern_editor.accept_pattern": "Accept pattern", "hex.builtin.view.pattern_editor.accept_pattern.desc": "One or more Patterns compatible with this data type has been found", "hex.builtin.view.pattern_editor.accept_pattern.pattern_language": "Patterns", @@ -1026,7 +1027,7 @@ "hex.builtin.view.pattern_editor.name": "Pattern editor", "hex.builtin.view.pattern_editor.no_in_out_vars": "Define some global variables with the 'in' or 'out' specifier for them to appear here.", "hex.builtin.view.pattern_editor.no_sections": "Create additional output sections to display and decode processed data by using the std::mem::create_section function.", - "hex.builtin.view.pattern_editor.no_virtual_files": "Visualize regions of data as a virtual folder structure by adding them using the hex::core::add_virtual_file function.", + "hex.builtin.view.pattern_data.virtual_files.no_virtual_files": "Visualize regions of data as a virtual folder structure by adding them using the hex::core::add_virtual_file function.", "hex.builtin.view.pattern_editor.no_env_vars": "The content of Environment Variables created here can be accessed from Pattern scripts using the std::env function.", "hex.builtin.view.pattern_editor.no_results": "no results", "hex.builtin.view.pattern_editor.of": "of", @@ -1093,7 +1094,7 @@ "hex.builtin.view.pattern_editor.menu.edit.continue_debugger": "Continue Debugger", "hex.builtin.view.pattern_editor.menu.edit.add_breakpoint": "Add Breakpoint", "hex.builtin.view.pattern_editor.tooltip.parent_offset": "Parent offset", - "hex.builtin.view.pattern_editor.virtual_files": "Virtual Filesystem", + "hex.builtin.view.pattern_data.virtual_files": "Virtual Filesystem", "hex.builtin.view.provider_settings.load_error": "An error occurred while trying to open this data source!", "hex.builtin.view.provider_settings.load_error_details": "An error occurred while trying to open this data source!\nDetails: {0}", "hex.builtin.view.provider_settings.load_popup": "Open Data", diff --git a/plugins/builtin/romfs/lang/es_ES.json b/plugins/builtin/romfs/lang/es_ES.json index 411f8b3cb..48363c9f0 100644 --- a/plugins/builtin/romfs/lang/es_ES.json +++ b/plugins/builtin/romfs/lang/es_ES.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "Ajustes", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "¡Ha ocurrido un error al intentar abrir este proveedor!", "hex.builtin.view.provider_settings.load_error_details": "¡Ha ocurrido un error al intentar abrir este proveedor!\nDetalles: {}", "hex.builtin.view.provider_settings.load_popup": "Abrir proveedor", diff --git a/plugins/builtin/romfs/lang/fr_FR.json b/plugins/builtin/romfs/lang/fr_FR.json index 1a2f0def8..4509327ab 100644 --- a/plugins/builtin/romfs/lang/fr_FR.json +++ b/plugins/builtin/romfs/lang/fr_FR.json @@ -969,7 +969,7 @@ "hex.builtin.view.pattern_editor.name": "Éditeur de modèles", "hex.builtin.view.pattern_editor.no_in_out_vars": "Définissez certaines variables globales avec le spécificateur 'in' ou 'out' pour qu'elles apparaissent ici.", "hex.builtin.view.pattern_editor.no_sections": "Créez des sections de sortie supplémentaires pour afficher et décoder les données traitées en utilisant la fonction std::mem::create_section.", - "hex.builtin.view.pattern_editor.no_virtual_files": "Visualisez les régions de données sous forme de structure de dossiers virtuels en les ajoutant à l'aide de la fonction hex::core::add_virtual_file.", + "hex.builtin.view.pattern_data.virtual_files.no_virtual_files": "Visualisez les régions de données sous forme de structure de dossiers virtuels en les ajoutant à l'aide de la fonction hex::core::add_virtual_file.", "hex.builtin.view.pattern_editor.no_env_vars": "Le contenu des variables d'environnement créées ici peut être accédé depuis les scripts de modèles en utilisant la fonction std::env.", "hex.builtin.view.pattern_editor.no_results": "aucun résultat", "hex.builtin.view.pattern_editor.of": "de", @@ -1019,7 +1019,7 @@ "hex.builtin.view.pattern_editor.shortcut.delete_word_left": "Supprimer un mot à gauche du curseur", "hex.builtin.view.pattern_editor.shortcut.delete_word_right": "Supprimer un mot à droite du curseur", "hex.builtin.view.pattern_editor.tooltip.parent_offset": "Décalage parent", - "hex.builtin.view.pattern_editor.virtual_files": "Système de fichiers virtuel", + "hex.builtin.view.pattern_data.virtual_files": "Système de fichiers virtuel", "hex.builtin.view.provider_settings.load_error": "Une erreur s'est produite lors de la tentative d'ouverture de ce fournisseur !", "hex.builtin.view.provider_settings.load_error_details": "Une erreur s'est produite lors de la tentative d'ouverture de ce fournisseur !\nDétails : {0}", "hex.builtin.view.provider_settings.load_popup": "Ouvrir les données", diff --git a/plugins/builtin/romfs/lang/hu_HU.json b/plugins/builtin/romfs/lang/hu_HU.json index 66ad53c4b..41217039d 100644 --- a/plugins/builtin/romfs/lang/hu_HU.json +++ b/plugins/builtin/romfs/lang/hu_HU.json @@ -901,7 +901,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "Csere", "hex.builtin.view.pattern_editor.replace_hint_history": " előzményekhez)", "hex.builtin.view.pattern_editor.settings": "Beállítások", - "hex.builtin.view.pattern_editor.virtual_files": "Virtuális fájlrendszer", + "hex.builtin.view.pattern_data.virtual_files": "Virtuális fájlrendszer", "hex.builtin.view.provider_settings.load_error": "Egy hiba lépett fel a forrás megnyitása során!", "hex.builtin.view.provider_settings.load_error_details": "Egy hiba lépett fel a forrás megnyitása során! Részletek: {0}", "hex.builtin.view.provider_settings.load_popup": "Forrás megnyitása", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index 2d62ccb06..97c1e90aa 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "Impostazioni", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "", "hex.builtin.view.provider_settings.load_error_details": "", "hex.builtin.view.provider_settings.load_popup": "Apri Provider", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 3b61be1a4..0e327f1ff 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "設定", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "ファイルを開く際にエラーが発生しました。", "hex.builtin.view.provider_settings.load_error_details": "", "hex.builtin.view.provider_settings.load_popup": "ファイルを開く", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index 62b7969e2..20b63a22d 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "설정", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "이 공급자를 여는 동안 오류가 발생했습니다!", "hex.builtin.view.provider_settings.load_error_details": "이 공급자를 여는 동안 오류가 발생했습니다!\n세부 정보: {}", "hex.builtin.view.provider_settings.load_popup": "공급자 열기", diff --git a/plugins/builtin/romfs/lang/pl_PL.json b/plugins/builtin/romfs/lang/pl_PL.json index c707377dc..5a82943f8 100644 --- a/plugins/builtin/romfs/lang/pl_PL.json +++ b/plugins/builtin/romfs/lang/pl_PL.json @@ -992,7 +992,7 @@ "hex.builtin.view.pattern_editor.no_in_out_vars": "Zdefiniuj niektóre zmienne globalne ze specyfikatorem 'in' lub 'out' aby pojawiły się tutaj.", "hex.builtin.view.pattern_editor.no_results": "brak wyników", "hex.builtin.view.pattern_editor.no_sections": "Utwórz dodatkowe sekcje wyjściowe do wyświetlania i dekodowania przetworzonych danych używając funkcji std::mem::create_section.", - "hex.builtin.view.pattern_editor.no_virtual_files": "Wizualizuj regiony danych jako wirtualną strukturę folderów dodając je używając funkcji hex::core::add_virtual_file.", + "hex.builtin.view.pattern_data.virtual_files.no_virtual_files": "Wizualizuj regiony danych jako wirtualną strukturę folderów dodając je używając funkcji hex::core::add_virtual_file.", "hex.builtin.view.pattern_editor.of": "z", "hex.builtin.view.pattern_editor.open_pattern": "Otwórz wzorzec", "hex.builtin.view.pattern_editor.replace_hint": "Zamień", @@ -1040,7 +1040,7 @@ "hex.builtin.view.pattern_editor.menu.edit.undo": "Cofnij", "hex.builtin.view.pattern_editor.shortcut.whole_word_toggle": "Przełącz wyszukiwanie całych słów", "hex.builtin.view.pattern_editor.tooltip.parent_offset": "Przesunięcie rodzica", - "hex.builtin.view.pattern_editor.virtual_files": "Wirtualny system plików", + "hex.builtin.view.pattern_data.virtual_files": "Wirtualny system plików", "hex.builtin.view.provider_settings.load_error": "Wystąpił błąd podczas próby otwarcia tego dostawcy!", "hex.builtin.view.provider_settings.load_error_details": "Wystąpił błąd podczas próby otwarcia tego dostawcy!\nSzczegóły: {0}", "hex.builtin.view.provider_settings.load_popup": "Otwórz dane", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index 1c3a1e42a..c348df695 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "Configurações", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "", "hex.builtin.view.provider_settings.load_error_details": "", "hex.builtin.view.provider_settings.load_popup": "Abrir Provedor", diff --git a/plugins/builtin/romfs/lang/ru_RU.json b/plugins/builtin/romfs/lang/ru_RU.json index facbe1203..961eb2b24 100644 --- a/plugins/builtin/romfs/lang/ru_RU.json +++ b/plugins/builtin/romfs/lang/ru_RU.json @@ -976,7 +976,7 @@ "hex.builtin.view.pattern_editor.shortcut.delete_word_left": "Удалить одно слово слева", "hex.builtin.view.pattern_editor.shortcut.delete_word_right": "Удалить одно слово справа", "hex.builtin.view.pattern_editor.tooltip.parent_offset": "Смещение родителя", - "hex.builtin.view.pattern_editor.virtual_files": "Виртуальная файловая система", + "hex.builtin.view.pattern_data.virtual_files": "Виртуальная файловая система", "hex.builtin.view.provider_settings.load_error": "При попытке открыть источник произошла ошибка!", "hex.builtin.view.provider_settings.load_error_details": "При попытке открыть источник произошла ошибка!\nПодробности: {0}", "hex.builtin.view.provider_settings.load_popup": "Открыть источник", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index ed26d1fa1..ccc45c1c4 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -973,7 +973,7 @@ "hex.builtin.view.pattern_editor.name": "模式编辑器", "hex.builtin.view.pattern_editor.no_in_out_vars": "使用 'in' 或 'out' 修饰符定义一些全局变量,以使它们出现在这里。", "hex.builtin.view.pattern_editor.no_sections": "使用 std::mem::create_section 函数创建附加输出区段以显示和解码处理后的数据。", - "hex.builtin.view.pattern_editor.no_virtual_files": "通过 hex::core::add_virtual_file 函数添加数据区域,将其可视化为虚拟文件夹结构。", + "hex.builtin.view.pattern_data.virtual_files.no_virtual_files": "通过 hex::core::add_virtual_file 函数添加数据区域,将其可视化为虚拟文件夹结构。", "hex.builtin.view.pattern_editor.no_env_vars": "此处创建的环境变量内容可通过 std::env 函数在模式脚本中访问。", "hex.builtin.view.pattern_editor.no_results": "无结果。", "hex.builtin.view.pattern_editor.of": "的", @@ -1023,7 +1023,7 @@ "hex.builtin.view.pattern_editor.shortcut.delete_word_left": "删除光标左侧的单词", "hex.builtin.view.pattern_editor.shortcut.delete_word_right": "删除光标右侧的单词", "hex.builtin.view.pattern_editor.tooltip.parent_offset": "父偏移", - "hex.builtin.view.pattern_editor.virtual_files": "虚拟文件系统", + "hex.builtin.view.pattern_data.virtual_files": "虚拟文件系统", "hex.builtin.view.provider_settings.load_error": "尝试打开此提供器时出现错误!", "hex.builtin.view.provider_settings.load_error_details": "打开此提供者时出现错误:\n详细信息:{}", "hex.builtin.view.provider_settings.load_popup": "打开提供器", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index 73856ab04..f47c37914 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -893,7 +893,7 @@ "hex.builtin.view.pattern_editor.replace_hint": "", "hex.builtin.view.pattern_editor.replace_hint_history": "", "hex.builtin.view.pattern_editor.settings": "設定", - "hex.builtin.view.pattern_editor.virtual_files": "", + "hex.builtin.view.pattern_data.virtual_files": "", "hex.builtin.view.provider_settings.load_error": "An error occurred while trying to open this provider!", "hex.builtin.view.provider_settings.load_error_details": "", "hex.builtin.view.provider_settings.load_popup": "開啟提供者", diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index b57529ff3..bcf2a0dba 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #include @@ -40,6 +42,7 @@ namespace hex::plugin::builtin { }); EventPatternEvaluating::subscribe(this, [this]{ + m_virtualFiles->clear(); for (auto &drawers : m_patternDrawer.all()) for (auto &[id, drawer] : drawers) drawer->reset(); @@ -83,6 +86,10 @@ namespace hex::plugin::builtin { (*m_patternDrawer)[0]->jumpToPattern(pattern); }); + RequestAddVirtualFile::subscribe(this, [this](const std::fs::path &path, const std::vector &data, Region region) { + m_virtualFiles->emplace_back(path, data, region); + }); + ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64, size_t) -> std::set { return { m_hoveredPatternRegion }; }); @@ -93,6 +100,105 @@ namespace hex::plugin::builtin { EventPatternExecuted::unsubscribe(this); } + + static void loadPatternAsMemoryProvider(const VirtualFile *file) { + ImHexApi::Provider::add(file->data, wolv::util::toUTF8String(file->path.filename())); + } + + static void drawVirtualFileTree(const std::vector &virtualFiles, u32 level = 0) { + static int levelId = 0; + if (level == 0) + levelId = 1; + + ImGui::PushID(level + 1); + ON_SCOPE_EXIT { ImGui::PopID(); }; + + std::map> currFolderEntries; + for (const auto &file : virtualFiles) { + const auto &path = file->path; + + auto currSegment = wolv::io::fs::toNormalizedPathString(*std::next(path.begin(), level)); + if (std::distance(path.begin(), path.end()) == ptrdiff_t(level + 1)) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + ImGui::TextUnformatted(ICON_VS_FILE); + ImGui::PushID(levelId); + ImGui::SameLine(); + + ImGui::TreeNodeEx(currSegment.c_str(), ImGuiTreeNodeFlags_DrawLinesToNodes | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); + if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsItemHovered() && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) { + ImGui::OpenPopup("##virtual_files_context_menu"); + } + if (ImGui::BeginPopup("##virtual_files_context_menu")) { + if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.open_in_new_provider"_lang, nullptr, false)) { + loadPatternAsMemoryProvider(file); + } + ImGui::EndPopup(); + } + if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && ImGui::IsItemHovered()) { + loadPatternAsMemoryProvider(file); + } + ImGui::PopID(); + levelId += 1; + continue; + } + + currFolderEntries[currSegment].emplace_back(file); + } + + int id = 1; + for (const auto &[segment, entries] : currFolderEntries) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + ImGui::PushStyleVarX(ImGuiStyleVar_FramePadding, 0.0F); + + if (level == 0) { + ImGui::TextUnformatted(ICON_VS_DATABASE); + } else { + ImGui::TextUnformatted(ICON_VS_FOLDER); + } + + ImGui::PushID(id); + + ImGui::SameLine(0, 20_scaled); + + const auto open = ImGui::TreeNodeEx("##Segment", ImGuiTreeNodeFlags_DrawLinesToNodes | ImGuiTreeNodeFlags_SpanLabelWidth | ImGuiTreeNodeFlags_OpenOnArrow); + ImGui::SameLine(); + ImGui::TextUnformatted(segment.c_str()); + ImGui::PopStyleVar(); + if (open) { + drawVirtualFileTree(entries, level + 1); + ImGui::TreePop(); + } + + ImGui::PopID(); + id += 1; + } + } + + static void setItemInfoTooltip(const char *title, const char *description) { + if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) { + ImGui::SetNextWindowSize(scaled(300, 0), ImGuiCond_Always); + if (ImGui::BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None)) { + if (ImGuiExt::BeginSubWindow(title)) { + ImGuiExt::TextFormattedWrapped("{}", description); + } + ImGuiExt::EndSubWindow(); + ImGui::EndTooltip(); + } + } + } + + static void selectFirstTabItem() { + auto tabBar = ImGui::GetCurrentTabBar(); + if (tabBar != nullptr && tabBar->Tabs.Size > 0) { + tabBar->SelectedTabId = tabBar->Tabs.front().ID; + } + } + + void ViewPatternData::drawContent() { // Draw the pattern tree if the provider is valid if (ImHexApi::Provider::isValid()) { @@ -156,65 +262,106 @@ namespace hex::plugin::builtin { } constexpr static auto SimplifiedEditorAttribute = "hex::editor_export"; - if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock()) && patternsValid) { - const auto &patternSet = runtime.getPatternsWithAttribute(SimplifiedEditorAttribute); - std::vector patterns = { patternSet.begin(), patternSet.end() }; - std::ranges::sort(patterns, [](const pl::ptrn::Pattern *a, const pl::ptrn::Pattern *b) { - return a->getOffset() < b->getOffset() || a->getDisplayName() < b->getDisplayName(); - }); + if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock())) { + constexpr static auto SimplifiedEditorTabName = "hex.builtin.view.pattern_data.simplified_editor"_lang; + const auto simplifiedEditorPatterns = [&] { + const auto &patternSet = runtime.getPatternsWithAttribute(SimplifiedEditorAttribute); - if (!patterns.empty()) { - constexpr auto TabName = "hex.builtin.view.pattern_data.simplified_editor"_lang; + std::vector result = { patternSet.begin(), patternSet.end() }; + std::ranges::sort(result, [](const pl::ptrn::Pattern *a, const pl::ptrn::Pattern *b) { + return a->getOffset() < b->getOffset() || a->getDisplayName() < b->getDisplayName(); + }); - ImGui::TabItemSpacing("##spacing", 0, ImGui::GetContentRegionAvail().x - ImGui::TabItemCalcSize(TabName, false).x); - if (ImGui::BeginTabItem(TabName, nullptr, ImGuiTabItemFlags_Trailing)) { - if (ImGui::BeginChild("##editor")) { - for (const auto &pattern : patterns) { - ImGui::PushID(pattern); - try { - const auto attribute = pattern->getAttributeArguments(SimplifiedEditorAttribute); + return result; + }(); - const auto name = attribute.size() >= 1 ? attribute[0].toString() : pattern->getDisplayName(); - const auto description = attribute.size() >= 2 ? attribute[1].toString() : pattern->getComment(); + constexpr static auto VirtualFilesTabName = "hex.builtin.view.pattern_data.virtual_files"_lang; - const auto widgetPos = 200_scaled; - ImGui::TextUnformatted(name.c_str()); - ImGui::SameLine(0, 20_scaled); - if (ImGui::GetCursorPosX() < widgetPos) - ImGui::SetCursorPosX(widgetPos); + float spacingWidth = ImGui::GetContentRegionAvail().x; - ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, 0); - ImGui::PushItemWidth(-50_scaled); - pattern->accept(m_patternValueEditor); - ImGui::PopItemWidth(); - ImGui::PopStyleVar(); + spacingWidth -= ImGui::TabItemCalcSize(ICON_TA_ACCESSIBLE, false).x; + spacingWidth -= ImGui::TabItemCalcSize(ICON_TA_BINARY_TREE, false).x; - if (!description.empty()) { - ImGui::PushFont(nullptr, ImGui::GetFontSize() * 0.8F); - ImGui::BeginDisabled(); - ImGui::Indent(); - ImGui::TextWrapped("%s", description.c_str()); - ImGui::Unindent(); - ImGui::EndDisabled(); - ImGui::PopFont(); - } + ImGui::TabItemSpacing("##spacing", ImGuiTabItemFlags_None, spacingWidth); - ImGui::Separator(); + ImGui::BeginDisabled(simplifiedEditorPatterns.empty()); + if (ImGui::BeginTabItem(ICON_TA_ACCESSIBLE, nullptr, ImGuiTabItemFlags_Trailing)) { + if (simplifiedEditorPatterns.empty()) + selectFirstTabItem(); - } catch (const std::exception &e) { - ImGui::TextUnformatted(pattern->getDisplayName().c_str()); - ImGui::TextUnformatted(e.what()); + if (ImGui::BeginChild("##editor")) { + for (const auto &pattern : simplifiedEditorPatterns) { + ImGui::PushID(pattern); + try { + const auto attribute = pattern->getAttributeArguments(SimplifiedEditorAttribute); + + const auto name = attribute.size() >= 1 ? attribute[0].toString() : pattern->getDisplayName(); + const auto description = attribute.size() >= 2 ? attribute[1].toString() : pattern->getComment(); + + const auto widgetPos = 200_scaled; + ImGui::TextUnformatted(name.c_str()); + ImGui::SameLine(0, 20_scaled); + if (ImGui::GetCursorPosX() < widgetPos) + ImGui::SetCursorPosX(widgetPos); + + ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, 0); + ImGui::PushItemWidth(-50_scaled); + pattern->accept(m_patternValueEditor); + ImGui::PopItemWidth(); + ImGui::PopStyleVar(); + + if (!description.empty()) { + ImGui::PushFont(nullptr, ImGui::GetFontSize() * 0.8F); + ImGui::BeginDisabled(); + ImGui::Indent(); + ImGui::TextWrapped("%s", description.c_str()); + ImGui::Unindent(); + ImGui::EndDisabled(); + ImGui::PopFont(); } - ImGui::PopID(); + ImGui::Separator(); + + } catch (const std::exception &e) { + ImGui::TextUnformatted(pattern->getDisplayName().c_str()); + ImGui::TextUnformatted(e.what()); } - ImGui::EndChild(); + ImGui::PopID(); } - ImGui::EndTabItem(); + ImGui::EndChild(); } + + ImGui::EndTabItem(); } + ImGui::EndDisabled(); + + if (simplifiedEditorPatterns.empty()) + setItemInfoTooltip(SimplifiedEditorTabName, "hex.builtin.view.pattern_data.simplified_editor.no_patterns"_lang); + + ImGui::BeginDisabled(m_virtualFiles->empty()); + if (ImGui::BeginTabItem(ICON_TA_BINARY_TREE, nullptr, ImGuiTabItemFlags_Trailing)) { + if (m_virtualFiles->empty()) + selectFirstTabItem(); + + std::vector virtualFilePointers; + for (const auto &file : *m_virtualFiles) + virtualFilePointers.emplace_back(&file); + + if (ImGui::BeginTable("##virtual_file_tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImGui::GetContentRegionAvail())) { + ImGui::TableSetupColumn("##path", ImGuiTableColumnFlags_WidthStretch); + drawVirtualFileTree(virtualFilePointers); + + ImGui::EndTable(); + } + + ImGui::EndTabItem(); + } + ImGui::EndDisabled(); + + if (m_virtualFiles->empty()) + setItemInfoTooltip(VirtualFilesTabName, "hex.builtin.view.pattern_data.virtual_files.no_virtual_files"_lang); } ImGui::EndTabBar(); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index f1cd77344..0281e6cce 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -285,74 +285,6 @@ namespace hex::plugin::builtin { return langDef; } - int levelId; - - static void loadPatternAsMemoryProvider(const ViewPatternEditor::VirtualFile *file) { - ImHexApi::Provider::add(file->data, wolv::util::toUTF8String(file->path.filename())); - } - - static void drawVirtualFileTree(const std::vector &virtualFiles, u32 level = 0) { - ImGui::PushID(level + 1); - ON_SCOPE_EXIT { ImGui::PopID(); }; - - std::map> currFolderEntries; - for (const auto &file : virtualFiles) { - const auto &path = file->path; - - auto currSegment = wolv::io::fs::toNormalizedPathString(*std::next(path.begin(), level)); - if (std::distance(path.begin(), path.end()) == ptrdiff_t(level + 1)) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - ImGui::TextUnformatted(ICON_VS_FILE); - ImGui::PushID(levelId); - ImGui::SameLine(); - - ImGui::TreeNodeEx(currSegment.c_str(), ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen); - if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsItemHovered() && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) { - ImGui::OpenPopup("##virtual_files_context_menu"); - } - if (ImGui::BeginPopup("##virtual_files_context_menu")) { - if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.open_in_new_provider"_lang, nullptr, false)) { - loadPatternAsMemoryProvider(file); - } - ImGui::EndPopup(); - } - if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && ImGui::IsItemHovered()) { - loadPatternAsMemoryProvider(file); - } - ImGui::PopID(); - levelId +=1; - continue; - } - - currFolderEntries[currSegment].emplace_back(file); - } - - int id = 1; - for (const auto &[segment, entries] : currFolderEntries) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - if (level == 0) { - ImGui::TextUnformatted(ICON_VS_DATABASE); - } else { - ImGui::TextUnformatted(ICON_VS_FOLDER); - } - - ImGui::PushID(id); - - ImGui::SameLine(); - if (ImGui::TreeNodeEx(segment.c_str(), ImGuiTreeNodeFlags_SpanFullWidth)) { - drawVirtualFileTree(entries, level + 1); - ImGui::TreePop(); - } - - ImGui::PopID(); - id += 1; - } - } - ViewPatternEditor::ViewPatternEditor() : View::Window("hex.builtin.view.pattern_editor.name", ICON_VS_SYMBOL_NAMESPACE) { m_editorRuntime = std::make_unique(); ContentRegistry::PatternLanguage::configureRuntime(*m_editorRuntime, nullptr); @@ -452,6 +384,23 @@ namespace hex::plugin::builtin { drawTextEditorGotoLinePopup(editor); } + void ViewPatternEditor::drawPatternSettings() { + const auto size = scaled(500, 150); + + if (ImGuiExt::BeginSubWindow("hex.builtin.view.pattern_editor.settings"_lang, nullptr, size)) { + this->drawVariableSettings(*m_patternVariables); + } + ImGuiExt::EndSubWindow(); + + ImGui::NewLine(); + + if (ImGuiExt::BeginSubWindow("hex.builtin.view.pattern_editor.env_vars"_lang, nullptr, size)) { + this->drawEnvVars(*m_envVarEntries); + } + ImGuiExt::EndSubWindow(); + } + + void ViewPatternEditor::drawContent() { auto provider = ImHexApi::Provider::get(); @@ -470,11 +419,27 @@ namespace hex::plugin::builtin { defaultEditorSize.y *= 0.66F; fonts::CodeEditor().push(); + ImGui::SetNextWindowSizeConstraints( + ImVec2( + defaultEditorSize.x, + ImGui::GetTextLineHeightWithSpacing() * 2 + ), + ImVec2( + defaultEditorSize.x, + std::min( + ImGui::GetContentRegionAvail().y - ImGui::GetTextLineHeightWithSpacing() * 4, + ImGui::GetContentRegionAvail().y * 0.8F + ) + ) + ); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); if (ImGui::BeginChild("##pattern_editor_resizer", defaultEditorSize, ImGuiChildFlags_ResizeY)) { m_textEditor.get(provider).render("##pattern_editor", ImGui::GetContentRegionAvail(), false); m_textEditorHoverBox = ImGui::GetCurrentWindow()->Rect(); } ImGui::EndChild(); + ImGui::PopStyleVar(2); fonts::CodeEditor().pop(); m_consoleHoverBox = ImGui::GetCurrentWindow()->Rect(); @@ -499,35 +464,28 @@ namespace hex::plugin::builtin { } auto settingsSize = ImGui::GetContentRegionAvail(); - settingsSize.y -= ImGui::GetTextLineHeightWithSpacing() * 2.5F; + if (m_debuggerActive) { + settingsSize.y -= ImGui::GetTextLineHeightWithSpacing() * 2.5F; - if (ImGui::BeginTabBar("##settings")) { - const auto startY = ImGui::GetCursorPosY(); + if (ImGui::BeginTabBar("##settings")) { + const auto startY = ImGui::GetCursorPosY(); - if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.console"_lang)) { - this->drawConsole(settingsSize); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.env_vars"_lang)) { - this->drawEnvVars(settingsSize, *m_envVarEntries); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.settings"_lang)) { - this->drawVariableSettings(settingsSize, *m_patternVariables); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.virtual_files"_lang)) { - this->drawVirtualFiles(settingsSize, *m_virtualFiles); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.debugger"_lang)) { - this->drawDebugger(settingsSize); - ImGui::EndTabItem(); - } + if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.console"_lang)) { + this->drawConsole(settingsSize); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.debugger"_lang)) { + this->drawDebugger(settingsSize); + ImGui::EndTabItem(); + } - ImGui::SetCursorPosY(startY + settingsSize.y + ImGui::GetStyle().ItemSpacing.y * 2); + ImGui::SetCursorPosY(startY + settingsSize.y + ImGui::GetStyle().ItemSpacing.y * 2); - ImGui::EndTabBar(); + ImGui::EndTabBar(); + } + } else { + settingsSize.y -= ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y; + this->drawConsole(settingsSize); } ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1); @@ -611,7 +569,7 @@ namespace hex::plugin::builtin { } ImGui::SetItemTooltip("%s", "hex.builtin.view.pattern_editor.auto"_lang.get()); - ImGui::SameLine(); + ImGui::SameLine(0, 5_scaled); bool synced = m_sourceCode.isSynced(); if (ImGuiExt::DimmedIconToggle(ICON_VS_REPO_PINNED, &synced)) { @@ -619,6 +577,20 @@ namespace hex::plugin::builtin { } ImGui::SetItemTooltip("%s", "hex.builtin.setting.general.sync_pattern_source"_lang.get()); + ImGui::SameLine(0, 10_scaled); + + if (ImGuiExt::DimmedIconButton(ICON_VS_SETTINGS_GEAR, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { + ImGui::OpenPopup("hex.builtin.view.pattern_editor.pattern_settings"_lang); + } + + ImGui::SameLine(0, 0); + + ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos() + ImVec2(0, ImGui::GetTextLineHeightWithSpacing()), ImGuiCond_Always, ImVec2(0.0F, 1.0F)); + if (ImGui::BeginPopup("hex.builtin.view.pattern_editor.pattern_settings"_lang)) { + this->drawPatternSettings(); + ImGui::EndPopup(); + } + ImGui::SameLine(); ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); ImGui::SameLine(); @@ -1076,10 +1048,10 @@ namespace hex::plugin::builtin { ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y + 1_scaled); } - void ViewPatternEditor::drawEnvVars(ImVec2 size, std::list &envVars) { + void ViewPatternEditor::drawEnvVars(std::list &envVars) { static u32 envVarCounter = 1; - if (ImGui::BeginChild("##env_vars", size, true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + if (ImGui::BeginChild("##env_vars", ImGui::GetContentRegionAvail(), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { if (envVars.size() <= 1) { ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_env_vars"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); } @@ -1184,9 +1156,9 @@ namespace hex::plugin::builtin { ImGui::EndChild(); } - void ViewPatternEditor::drawVariableSettings(ImVec2 size, std::map &patternVariables) { + void ViewPatternEditor::drawVariableSettings(std::map &patternVariables) { auto provider = ImHexApi::Provider::get(); - if (ImGui::BeginChild("##settings", size, true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + if (ImGui::BeginChild("##settings", ImGui::GetContentRegionAvail(), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { if (patternVariables.empty()) { ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_in_out_vars"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); } @@ -1250,26 +1222,6 @@ namespace hex::plugin::builtin { ImGui::EndChild(); } - void ViewPatternEditor::drawVirtualFiles(ImVec2 size, const std::vector &virtualFiles) const { - std::vector virtualFilePointers; - - for (const auto &file : virtualFiles) - virtualFilePointers.emplace_back(&file); - - if (ImGui::BeginTable("##virtual_file_tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) { - if (virtualFiles.empty()) { - ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_virtual_files"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); - } - - ImGui::TableSetupColumn("##path", ImGuiTableColumnFlags_WidthStretch); - levelId = 1; - drawVirtualFileTree(virtualFilePointers); - - ImGui::EndTable(); - } - } - - void ViewPatternEditor::drawDebugger(ImVec2 size) { auto provider = ImHexApi::Provider::get(); const auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); @@ -1278,22 +1230,9 @@ namespace hex::plugin::builtin { auto &evaluator = runtime.getInternals().evaluator; m_breakpoints = m_textEditor.get(provider).getBreakpoints(); evaluator->setBreakpoints(m_breakpoints); - const auto line = m_textEditor.get(provider).getCursorPosition().m_line + 1; - if (!m_breakpoints->contains(line)) { - if (ImGuiExt::IconButton(ICON_VS_CIRCLE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) { - evaluator->addBreakpoint(line); - } - ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.add_tooltip"_lang); - } else { - if (ImGuiExt::IconButton(ICON_VS_CIRCLE_FILLED, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) { - evaluator->removeBreakpoint(line); - } - ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.remove_tooltip"_lang); - } m_breakpoints = evaluator->getBreakpoints(); m_textEditor.get(provider).setBreakpoints(m_breakpoints); - ImGui::SameLine(); if (*m_breakpointHit) { auto displayValue = [&](const auto &parent, size_t index) { @@ -1703,7 +1642,6 @@ namespace hex::plugin::builtin { m_consoleNeedsUpdate = true; m_consoleEditor.get(provider).setText(""); - m_virtualFiles->clear(); m_accessHistory = {}; m_accessHistoryIndex = 0; @@ -1718,18 +1656,20 @@ namespace hex::plugin::builtin { ContentRegistry::PatternLanguage::configureRuntime(runtime, provider); runtime.getInternals().evaluator->setBreakpointHitCallback([this, &runtime, provider] { m_debuggerScopeIndex = 0; - *m_breakpointHit = true; + m_breakpointHit.get(provider) = true; + m_debuggerActive.get(provider) = true; m_resetDebuggerVariables = true; auto optPauseLine = runtime.getInternals().evaluator->getPauseLine(); if (optPauseLine.has_value()) m_textEditor.get(provider).jumpToLine(optPauseLine.value() - 1); - while (*m_breakpointHit) { + while (m_breakpointHit.get(provider)) { std::this_thread::sleep_for(std::chrono::milliseconds(100LL)); } }); - task.setInterruptCallback([this, &runtime] { - m_breakpointHit = false; + task.setInterruptCallback([this, &runtime, provider] { + m_breakpointHit.get(provider) = false; + m_debuggerActive.get(provider) = false; runtime.abort(); }); @@ -1791,6 +1731,7 @@ namespace hex::plugin::builtin { fmt::format("I: Evaluation took {}", std::chrono::duration(runtime.getLastRunningTime())) ); m_consoleNeedsUpdate = true; + m_debuggerActive.get(provider) = false; }; @@ -1896,10 +1837,6 @@ namespace hex::plugin::builtin { }); - RequestAddVirtualFile::subscribe(this, [this](const std::fs::path &path, const std::vector &data, Region region) { - m_virtualFiles->emplace_back(path, data, region); - }); - } static void createNestedMenu(const std::vector &menus, const std::function &function) {