mirror of https://github.com/WerWolv/ImHex
impr: Move items from pattern editor console area to more appropriate places
This commit is contained in:
parent
be66e3fe79
commit
32e3a4e74f
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
struct VirtualFile {
|
||||
std::fs::path path;
|
||||
std::vector<u8> data;
|
||||
Region region;
|
||||
};
|
||||
|
||||
class ViewPatternData : public View::Window {
|
||||
public:
|
||||
ViewPatternData();
|
||||
|
|
@ -26,6 +32,8 @@ namespace hex::plugin::builtin {
|
|||
PerProvider<std::map<u64, std::unique_ptr<ui::PatternDrawer>>> m_patternDrawer;
|
||||
Region m_hoveredPatternRegion = Region::Invalid();
|
||||
ui::PatternValueEditor m_patternValueEditor;
|
||||
PerProvider<std::vector<VirtualFile>> m_virtualFiles;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -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<u8> data;
|
||||
Region region;
|
||||
};
|
||||
|
||||
enum class DangerousFunctionPerms : u8 {
|
||||
Ask,
|
||||
Allow,
|
||||
|
|
@ -165,13 +159,13 @@ namespace hex::plugin::builtin {
|
|||
PerProvider<std::map<std::string, pl::core::Token::Literal>> m_lastEvaluationOutVars;
|
||||
PerProvider<std::map<std::string, PatternVariable>> m_patternVariables;
|
||||
|
||||
PerProvider<std::vector<VirtualFile>> m_virtualFiles;
|
||||
|
||||
PerProvider<std::list<EnvVar>> m_envVarEntries;
|
||||
|
||||
PerProvider<TaskHolder> m_analysisTask;
|
||||
PerProvider<bool> m_shouldAnalyze;
|
||||
PerProvider<bool> m_breakpointHit;
|
||||
PerProvider<bool> m_debuggerActive;
|
||||
PerProvider<std::unique_ptr<ui::PatternDrawer>> m_debuggerDrawer;
|
||||
std::atomic<bool> 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<EnvVar> &envVars);
|
||||
void drawVariableSettings(ImVec2 size, std::map<std::string, PatternVariable> &patternVariables);
|
||||
void drawVirtualFiles(ImVec2 size, const std::vector<VirtualFile> &virtualFiles) const;
|
||||
void drawDebugger(ImVec2 size);
|
||||
|
||||
void drawPatternSettings();
|
||||
void drawEnvVars(std::list<EnvVar> &envVars);
|
||||
void drawVariableSettings(std::map<std::string, PatternVariable> &patternVariables);
|
||||
|
||||
void drawPatternTooltip(pl::ptrn::Pattern *pattern);
|
||||
|
||||
void drawTextEditorFindReplacePopup(ui::TextEditor *textEditor);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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": "ファイルを開く",
|
||||
|
|
|
|||
|
|
@ -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": "공급자 열기",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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": "Открыть источник",
|
||||
|
|
|
|||
|
|
@ -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": "打开提供器",
|
||||
|
|
|
|||
|
|
@ -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": "開啟提供者",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <hex/api/events/events_interaction.hpp>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <fonts/tabler_icons.hpp>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include <pl/patterns/pattern.hpp>
|
||||
|
|
@ -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<u8> &data, Region region) {
|
||||
m_virtualFiles->emplace_back(path, data, region);
|
||||
});
|
||||
|
||||
ImHexApi::HexEditor::addHoverHighlightProvider([this](const prv::Provider *, u64, size_t) -> std::set<Region> {
|
||||
return { m_hoveredPatternRegion };
|
||||
});
|
||||
|
|
@ -93,6 +100,105 @@ namespace hex::plugin::builtin {
|
|||
EventPatternExecuted::unsubscribe(this);
|
||||
}
|
||||
|
||||
|
||||
static void loadPatternAsMemoryProvider(const VirtualFile *file) {
|
||||
ImHexApi::Provider::add<prv::MemoryProvider>(file->data, wolv::util::toUTF8String(file->path.filename()));
|
||||
}
|
||||
|
||||
static void drawVirtualFileTree(const std::vector<const VirtualFile*> &virtualFiles, u32 level = 0) {
|
||||
static int levelId = 0;
|
||||
if (level == 0)
|
||||
levelId = 1;
|
||||
|
||||
ImGui::PushID(level + 1);
|
||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||
|
||||
std::map<std::string, std::vector<const VirtualFile*>> 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<pl::ptrn::Pattern*> 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<pl::ptrn::Pattern*> 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<const VirtualFile*> 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();
|
||||
|
|
|
|||
|
|
@ -285,74 +285,6 @@ namespace hex::plugin::builtin {
|
|||
return langDef;
|
||||
}
|
||||
|
||||
int levelId;
|
||||
|
||||
static void loadPatternAsMemoryProvider(const ViewPatternEditor::VirtualFile *file) {
|
||||
ImHexApi::Provider::add<prv::MemoryProvider>(file->data, wolv::util::toUTF8String(file->path.filename()));
|
||||
}
|
||||
|
||||
static void drawVirtualFileTree(const std::vector<const ViewPatternEditor::VirtualFile*> &virtualFiles, u32 level = 0) {
|
||||
ImGui::PushID(level + 1);
|
||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||
|
||||
std::map<std::string, std::vector<const ViewPatternEditor::VirtualFile*>> 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<pl::PatternLanguage>();
|
||||
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<EnvVar> &envVars) {
|
||||
void ViewPatternEditor::drawEnvVars(std::list<EnvVar> &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<std::string, PatternVariable> &patternVariables) {
|
||||
void ViewPatternEditor::drawVariableSettings(std::map<std::string, PatternVariable> &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<VirtualFile> &virtualFiles) const {
|
||||
std::vector<const VirtualFile*> 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<double>(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<u8> &data, Region region) {
|
||||
m_virtualFiles->emplace_back(path, data, region);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static void createNestedMenu(const std::vector<std::string> &menus, const std::function<void()> &function) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue