From c0c000914b28ecb28b1c54e848cd5c67098ff0cc Mon Sep 17 00:00:00 2001 From: Stephen Pick <3457029+the-claw@users.noreply.github.com> Date: Mon, 29 Jun 2026 10:15:39 +0100 Subject: [PATCH 1/4] Latest imhex and fixes for same --- dep/build.py | 8 +- src/gui2/abstractsectorview.cc | 4 + src/gui2/abstractsectorview.h | 1 + src/gui2/build.py | 336 +++-- src/gui2/configview.cc | 4 + src/gui2/configview.h | 1 + src/gui2/controlpanelview.cc | 4 + src/gui2/controlpanelview.h | 1 + src/gui2/diskprovider.cc | 4 +- src/gui2/diskprovider.h | 2 +- .../imhex_overrides/achievement_manager.cpp | 3 + src/gui2/imhex_overrides/imconfig.h | 21 +- src/gui2/imhex_overrides/main_menu_items.cpp | 1320 +++++++++++------ src/gui2/imhex_overrides/menu_items.cpp | 15 + src/gui2/imhex_overrides/providers.cpp | 156 +- src/gui2/imhex_overrides/views.cpp | 4 +- src/gui2/logview.cc | 4 + src/gui2/logview.h | 1 + src/gui2/summaryview.cc | 4 + src/gui2/summaryview.h | 1 + src/gui2/visualiserview.cc | 4 + src/gui2/visualiserview.h | 1 + 22 files changed, 1267 insertions(+), 632 deletions(-) diff --git a/dep/build.py b/dep/build.py index ddd94bca..002c5fb9 100644 --- a/dep/build.py +++ b/dep/build.py @@ -772,6 +772,7 @@ "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_struct.cpp", "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_ternary_expression.cpp", "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_try_catch_statement.cpp", + "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_type_application.cpp", "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_type_decl.cpp", "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_type_operator.cpp", "dep/r/pattern-language/lib/source/pl/core/ast/ast_node_union.cpp", @@ -848,8 +849,10 @@ "pl/core/ast/ast_node_rvalue_assignment.hpp", "pl/core/ast/ast_node_scope_resolution.hpp", "pl/core/ast/ast_node_struct.hpp", + "pl/core/ast/ast_node_template_parameter.hpp", "pl/core/ast/ast_node_ternary_expression.hpp", "pl/core/ast/ast_node_try_catch_statement.hpp", + "pl/core/ast/ast_node_type_appilication.hpp", "pl/core/ast/ast_node_type_decl.hpp", "pl/core/ast/ast_node_type_operator.hpp", "pl/core/ast/ast_node_union.hpp", @@ -899,8 +902,7 @@ git_repository( name="patternlanguage_repo", url="https://github.com/WerWolv/PatternLanguage", - branch="ImHex-v1.38.0", - commit="f97999d4da8f64df0706227f8b5a6a861e5a95ff", + branch="master", path="dep/r/pattern-language", ), ], @@ -953,7 +955,7 @@ git_repository( name="imhex_repo", - url="https://github.com/davidgiven/ImHex", + url="https://github.com/the-claw/ImHex", branch="master", path="dep/r/imhex", ) diff --git a/src/gui2/abstractsectorview.cc b/src/gui2/abstractsectorview.cc index 65e5ae61..9f28ac9a 100644 --- a/src/gui2/abstractsectorview.cc +++ b/src/gui2/abstractsectorview.cc @@ -198,3 +198,7 @@ void AbstractSectorView::drawContent() } } } + +void AbstractSectorView::drawHelpText() +{ +} \ No newline at end of file diff --git a/src/gui2/abstractsectorview.h b/src/gui2/abstractsectorview.h index 6d83d784..06961761 100644 --- a/src/gui2/abstractsectorview.h +++ b/src/gui2/abstractsectorview.h @@ -12,6 +12,7 @@ class AbstractSectorView : public hex::View::Window AbstractSectorView(const std::string& name); void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { diff --git a/src/gui2/build.py b/src/gui2/build.py index 94435f48..1d300752 100644 --- a/src/gui2/build.py +++ b/src/gui2/build.py @@ -124,12 +124,18 @@ "dep/r/imhex/lib/libimhex/source/api/theme_manager.cpp", "dep/r/imhex/lib/libimhex/source/api/tutorial_manager.cpp", "dep/r/imhex/lib/libimhex/source/api/workspace_manager.cpp", + "dep/r/imhex/lib/libimhex/source/data_processor/attribute.cpp", + "dep/r/imhex/lib/libimhex/source/data_processor/link.cpp", + "dep/r/imhex/lib/libimhex/source/data_processor/node.cpp", + "dep/r/imhex/lib/libimhex/source/helpers/binary_pattern.cpp", "dep/r/imhex/lib/libimhex/source/helpers/crypto.cpp", "dep/r/imhex/lib/libimhex/source/helpers/debugging.cpp", "dep/r/imhex/lib/libimhex/source/helpers/encoding_file.cpp", "dep/r/imhex/lib/libimhex/source/helpers/fs.cpp", "dep/r/imhex/lib/libimhex/source/helpers/http_requests.cpp", + "dep/r/imhex/lib/libimhex/source/helpers/http_requests_emscripten.cpp", "dep/r/imhex/lib/libimhex/source/helpers/http_requests_native.cpp", + "dep/r/imhex/lib/libimhex/source/helpers/imgui_hooks.cpp", "dep/r/imhex/lib/libimhex/source/helpers/keys.cpp", "dep/r/imhex/lib/libimhex/source/helpers/logger.cpp", "dep/r/imhex/lib/libimhex/source/helpers/magic.cpp", @@ -140,118 +146,129 @@ "dep/r/imhex/lib/libimhex/source/helpers/tar.cpp", "dep/r/imhex/lib/libimhex/source/helpers/udp_server.cpp", "dep/r/imhex/lib/libimhex/source/helpers/utils.cpp", + "dep/r/imhex/lib/libimhex/source/mcp/client.cpp", + "dep/r/imhex/lib/libimhex/source/mcp/server.cpp", "dep/r/imhex/lib/libimhex/source/providers/cached_provider.cpp", "dep/r/imhex/lib/libimhex/source/providers/memory_provider.cpp", "dep/r/imhex/lib/libimhex/source/providers/provider.cpp", "dep/r/imhex/lib/libimhex/source/providers/undo/stack.cpp", "dep/r/imhex/lib/libimhex/source/subcommands/subcommands.cpp", + "dep/r/imhex/lib/libimhex/source/test/tests.cpp", "dep/r/imhex/lib/libimhex/source/ui/banner.cpp", "dep/r/imhex/lib/libimhex/source/ui/imgui_imhex_extensions.cpp", "dep/r/imhex/lib/libimhex/source/ui/popup.cpp", "dep/r/imhex/lib/libimhex/source/ui/toast.cpp", "dep/r/imhex/lib/libimhex/source/ui/view.cpp", ], - hdrs={ - f: f"dep/r/imhex/lib/libimhex/include/{f}" - for f in [ - "hex.hpp", - "hex/api/achievement_manager.hpp", - "hex/api/content_registry/background_services.hpp", - "hex/api/content_registry/command_palette.hpp", - "hex/api/content_registry/communication_interface.hpp", - "hex/api/content_registry/data_formatter.hpp", - "hex/api/content_registry/data_information.hpp", - "hex/api/content_registry/data_inspector.hpp", - "hex/api/content_registry/data_processor.hpp", - "hex/api/content_registry/diffing.hpp", - "hex/api/content_registry/disassemblers.hpp", - "hex/api/content_registry/experiments.hpp", - "hex/api/content_registry/file_type_handler.hpp", - "hex/api/content_registry/hashes.hpp", - "hex/api/content_registry/hex_editor.hpp", - "hex/api/content_registry/pattern_language.hpp", - "hex/api/content_registry/provider.hpp", - "hex/api/content_registry/reports.hpp", - "hex/api/content_registry/settings.hpp", - "hex/api/content_registry/tools.hpp", - "hex/api/content_registry/user_interface.hpp", - "hex/api/content_registry/views.hpp", - "hex/api/event_manager.hpp", - "hex/api/events/events_gui.hpp", - "hex/api/events/events_interaction.hpp", - "hex/api/events/events_lifecycle.hpp", - "hex/api/events/events_provider.hpp", - "hex/api/events/requests_gui.hpp", - "hex/api/events/requests_interaction.hpp", - "hex/api/events/requests_lifecycle.hpp", - "hex/api/events/requests_provider.hpp", - "hex/api/imhex_api/bookmarks.hpp", - "hex/api/imhex_api/fonts.hpp", - "hex/api/imhex_api/hex_editor.hpp", - "hex/api/imhex_api/messaging.hpp", - "hex/api/imhex_api/provider.hpp", - "hex/api/imhex_api/system.hpp", - "hex/api/layout_manager.hpp", - "hex/api/localization_manager.hpp", - "hex/api/plugin_manager.hpp", - "hex/api/project_file_manager.hpp", - "hex/api/shortcut_manager.hpp", - "hex/api/task_manager.hpp", - "hex/api/theme_manager.hpp", - "hex/api/tutorial_manager.hpp", - "hex/api/workspace_manager.hpp", - "hex/api_urls.hpp", - "hex/data_processor/attribute.hpp", - "hex/data_processor/link.hpp", - "hex/data_processor/node.hpp", - "hex/helpers/auto_reset.hpp", - "hex/helpers/binary_pattern.hpp", - "hex/helpers/concepts.hpp", - "hex/helpers/crypto.hpp", - "hex/helpers/debugging.hpp", - "hex/helpers/default_paths.hpp", - "hex/helpers/encoding_file.hpp", - "hex/helpers/fmt.hpp", - "hex/helpers/fs.hpp", - "hex/helpers/http_requests.hpp", - "hex/helpers/http_requests_emscripten.hpp", - "hex/helpers/http_requests_native.hpp", - "hex/helpers/keys.hpp", - "hex/helpers/literals.hpp", - "hex/helpers/logger.hpp", - "hex/helpers/magic.hpp", - "hex/helpers/menu_items.hpp", - "hex/helpers/opengl.hpp", - "hex/helpers/patches.hpp", - "hex/helpers/scaling.hpp", - "hex/helpers/semantic_version.hpp", - "hex/helpers/tar.hpp", - "hex/helpers/types.hpp", - "hex/helpers/udp_server.hpp", - "hex/helpers/utils.hpp", - "hex/helpers/utils_linux.hpp", - "hex/helpers/utils_macos.hpp", - "hex/plugin.hpp", - "hex/providers/buffered_reader.hpp", - "hex/providers/cached_provider.hpp", - "hex/providers/memory_provider.hpp", - "hex/providers/overlay.hpp", - "hex/providers/provider.hpp", - "hex/providers/provider_data.hpp", - "hex/providers/undo_redo/operations/operation.hpp", - "hex/providers/undo_redo/operations/operation_group.hpp", - "hex/providers/undo_redo/stack.hpp", - "hex/subcommands/subcommands.hpp", - "hex/test/test_provider.hpp", - "hex/test/tests.hpp", - "hex/ui/banner.hpp", - "hex/ui/imgui_imhex_extensions.h", - "hex/ui/popup.hpp", - "hex/ui/toast.hpp", - "hex/ui/view.hpp", - "hex/ui/widgets.hpp", - ] - }, + hdrs=( + { + f: f"dep/r/imhex/lib/libimhex/include/{f}" + for f in [ + "hex.hpp", + "hex/api/achievement_manager.hpp", + "hex/api/content_registry/background_services.hpp", + "hex/api/content_registry/command_palette.hpp", + "hex/api/content_registry/communication_interface.hpp", + "hex/api/content_registry/data_formatter.hpp", + "hex/api/content_registry/data_information.hpp", + "hex/api/content_registry/data_inspector.hpp", + "hex/api/content_registry/data_processor.hpp", + "hex/api/content_registry/diffing.hpp", + "hex/api/content_registry/disassemblers.hpp", + "hex/api/content_registry/experiments.hpp", + "hex/api/content_registry/file_type_handler.hpp", + "hex/api/content_registry/hashes.hpp", + "hex/api/content_registry/hex_editor.hpp", + "hex/api/content_registry/pattern_language.hpp", + "hex/api/content_registry/provider.hpp", + "hex/api/content_registry/reports.hpp", + "hex/api/content_registry/settings.hpp", + "hex/api/content_registry/tools.hpp", + "hex/api/content_registry/user_interface.hpp", + "hex/api/content_registry/views.hpp", + "hex/api/event_manager.hpp", + "hex/api/events/events_gui.hpp", + "hex/api/events/events_interaction.hpp", + "hex/api/events/events_lifecycle.hpp", + "hex/api/events/events_provider.hpp", + "hex/api/events/requests_gui.hpp", + "hex/api/events/requests_interaction.hpp", + "hex/api/events/requests_lifecycle.hpp", + "hex/api/events/requests_provider.hpp", + "hex/api/imhex_api/bookmarks.hpp", + "hex/api/imhex_api/fonts.hpp", + "hex/api/imhex_api/hex_editor.hpp", + "hex/api/imhex_api/messaging.hpp", + "hex/api/imhex_api/provider.hpp", + "hex/api/imhex_api/system.hpp", + "hex/api/layout_manager.hpp", + "hex/api/localization_manager.hpp", + "hex/api/plugin_manager.hpp", + "hex/api/project_file_manager.hpp", + "hex/api/shortcut_manager.hpp", + "hex/api/task_manager.hpp", + "hex/api/theme_manager.hpp", + "hex/api/tutorial_manager.hpp", + "hex/api/workspace_manager.hpp", + "hex/api_urls.hpp", + "hex/data_processor/attribute.hpp", + "hex/data_processor/link.hpp", + "hex/data_processor/node.hpp", + "hex/helpers/auto_reset.hpp", + "hex/helpers/binary_pattern.hpp", + "hex/helpers/concepts.hpp", + "hex/helpers/crypto.hpp", + "hex/helpers/debugging.hpp", + "hex/helpers/default_paths.hpp", + "hex/helpers/encoding_file.hpp", + "hex/helpers/fmt.hpp", + "hex/helpers/fs.hpp", + "hex/helpers/http_requests.hpp", + "hex/helpers/http_requests_emscripten.hpp", + "hex/helpers/http_requests_native.hpp", + "hex/helpers/keys.hpp", + "hex/helpers/literals.hpp", + "hex/helpers/logger.hpp", + "hex/helpers/magic.hpp", + "hex/helpers/menu_items.hpp", + "hex/helpers/opengl.hpp", + "hex/helpers/patches.hpp", + "hex/helpers/scaling.hpp", + "hex/helpers/semantic_version.hpp", + "hex/helpers/tar.hpp", + "hex/helpers/types.hpp", + "hex/helpers/udp_server.hpp", + "hex/helpers/utils.hpp", + "hex/helpers/utils_linux.hpp", + "hex/helpers/utils_macos.hpp", + "hex/mcp/client.hpp", + "hex/mcp/server.hpp", + "hex/plugin.hpp", + "hex/providers/buffered_reader.hpp", + "hex/providers/cached_provider.hpp", + "hex/providers/memory_provider.hpp", + "hex/providers/overlay.hpp", + "hex/providers/provider.hpp", + "hex/providers/provider_data.hpp", + "hex/providers/undo_redo/operations/operation.hpp", + "hex/providers/undo_redo/operations/operation_group.hpp", + "hex/providers/undo_redo/stack.hpp", + "hex/subcommands/subcommands.hpp", + "hex/test/test_provider.hpp", + "hex/test/tests.hpp", + "hex/ui/banner.hpp", + "hex/ui/imgui_imhex_extensions.h", + "hex/ui/popup.hpp", + "hex/ui/toast.hpp", + "hex/ui/view.hpp", + "hex/ui/widgets.hpp", + ] + } + | { + f: f"dep/r/imhex/lib/trace/include/{f}" + for f in ["hex/trace/stacktrace.hpp", "hex/trace/exceptions.hpp"] + } + ), cflags=cflags, deps=[ ".+glfw3_lib", @@ -402,8 +419,10 @@ def plugin(name, id, srcs, hdrs, romfsdir, deps): "dep/r/imhex/plugins/ui/source/ui/text_editor/utf8.cpp", "dep/r/imhex/plugins/ui/source/ui/text_editor/render.cpp", "dep/r/imhex/plugins/ui/source/ui/text_editor/editor.cpp", + "dep/r/imhex/plugins/ui/source/ui/text_editor/codeFolder.cpp", "dep/r/imhex/plugins/ui/source/ui/hex_editor.cpp", "dep/r/imhex/plugins/ui/source/ui/markdown.cpp", + "dep/r/imhex/plugins/ui/source/ui/menu_items.cpp", "dep/r/imhex/plugins/ui/source/ui/pattern_drawer.cpp", "dep/r/imhex/plugins/ui/source/ui/pattern_value_editor.cpp", "dep/r/imhex/plugins/ui/source/ui/visualizer_drawer.cpp", @@ -444,6 +463,7 @@ def plugin(name, id, srcs, hdrs, romfsdir, deps): "./imhex_overrides/ui_items.cc", "./imhex_overrides/views.cpp", "./imhex_overrides/welcome.cc", + "dep/r/imhex/plugins/builtin/source/content/achievements.cpp", "dep/r/imhex/plugins/builtin/source/content/background_services.cpp", "dep/r/imhex/plugins/builtin/source/content/command_line_interface.cpp", "dep/r/imhex/plugins/builtin/source/content/command_palette_commands.cpp", @@ -451,23 +471,47 @@ def plugin(name, id, srcs, hdrs, romfsdir, deps): "dep/r/imhex/plugins/builtin/source/content/data_formatters.cpp", "dep/r/imhex/plugins/builtin/source/content/data_information_sections.cpp", "dep/r/imhex/plugins/builtin/source/content/data_inspector.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/basic_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/control_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/decode_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/logic_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/math_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/other_nodes.cpp", + "dep/r/imhex/plugins/builtin/source/content/data_processor_nodes/visual_nodes.cpp", "dep/r/imhex/plugins/builtin/source/content/data_visualizers.cpp", "dep/r/imhex/plugins/builtin/source/content/differing_byte_searcher.cpp", "dep/r/imhex/plugins/builtin/source/content/events.cpp", "dep/r/imhex/plugins/builtin/source/content/file_extraction.cpp", "dep/r/imhex/plugins/builtin/source/content/file_handlers.cpp", "dep/r/imhex/plugins/builtin/source/content/global_actions.cpp", + "dep/r/imhex/plugins/builtin/source/content/helpers/constants.cpp", "dep/r/imhex/plugins/builtin/source/content/init_tasks.cpp", + "dep/r/imhex/plugins/builtin/source/content/main_menu_items.cpp", + "dep/r/imhex/plugins/builtin/source/content/mcp_tools.cpp", "dep/r/imhex/plugins/builtin/source/content/minimap_visualizers.cpp", + "dep/r/imhex/plugins/builtin/source/content/out_of_box_experience.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_builtin_functions.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_builtin_types.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_pragmas.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_visualizers.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_visualizers/chunk_entropy.cpp", "dep/r/imhex/plugins/builtin/source/content/pl_visualizers/hex_viewer.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_base_address.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_decoded_string.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_fill.cpp", "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_find.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_goto.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_insert.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_page_size.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_paste_behaviour.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_remove.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_resize.cpp", + "dep/r/imhex/plugins/builtin/source/content/popups/hex_editor/popup_hex_editor_select.cpp", "dep/r/imhex/plugins/builtin/source/content/project.cpp", + "dep/r/imhex/plugins/builtin/source/content/providers.cpp", "dep/r/imhex/plugins/builtin/source/content/providers/base64_provider.cpp", + "dep/r/imhex/plugins/builtin/source/content/providers/command_provider.cpp", "dep/r/imhex/plugins/builtin/source/content/providers/disk_provider.cpp", "dep/r/imhex/plugins/builtin/source/content/providers/file_provider.cpp", "dep/r/imhex/plugins/builtin/source/content/providers/gdb_provider.cpp", @@ -502,13 +546,18 @@ def plugin(name, id, srcs, hdrs, romfsdir, deps): "dep/r/imhex/plugins/builtin/source/content/tools/tcp_client_server.cpp", "dep/r/imhex/plugins/builtin/source/content/tools/wiki_explainer.cpp", "dep/r/imhex/plugins/builtin/source/content/tools_entries.cpp", + "dep/r/imhex/plugins/builtin/source/content/tutorials/introduction.cpp", + "dep/r/imhex/plugins/builtin/source/content/tutorials/tutorials.cpp", + "dep/r/imhex/plugins/builtin/source/content/ui_items.cpp", + "dep/r/imhex/plugins/builtin/source/content/views.cpp", "dep/r/imhex/plugins/builtin/source/content/views/fullscreen/view_fullscreen_file_info.cpp", "dep/r/imhex/plugins/builtin/source/content/views/fullscreen/view_fullscreen_save_editor.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_about.cpp", + "dep/r/imhex/plugins/builtin/source/content/views/view_achievements.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_bookmarks.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_command_palette.cpp", - "dep/r/imhex/plugins/builtin/source/content/views/view_constants.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_data_inspector.cpp", + "dep/r/imhex/plugins/builtin/source/content/views/view_data_processor.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_find.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_hex_editor.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_highlight_rules.cpp", @@ -522,69 +571,84 @@ def plugin(name, id, srcs, hdrs, romfsdir, deps): "dep/r/imhex/plugins/builtin/source/content/views/view_store.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_theme_manager.cpp", "dep/r/imhex/plugins/builtin/source/content/views/view_tools.cpp", + "dep/r/imhex/plugins/builtin/source/content/views/view_tutorials.cpp", + "dep/r/imhex/plugins/builtin/source/content/welcome_screen.cpp", "dep/r/imhex/plugins/builtin/source/content/window_decoration.cpp", "dep/r/imhex/plugins/builtin/source/content/workspaces.cpp", "dep/r/imhex/plugins/builtin/source/plugin_builtin.cpp", + ], hdrs={ f: f"dep/r/imhex/plugins/builtin/include/{f}" for f in [ + "content/command_line_interface.hpp", + "content/data_processor_nodes.hpp", + "content/differing_byte_searcher.hpp", + "content/export_formatters/export_formatter.hpp", "content/export_formatters/export_formatter_csv.hpp", - "content/export_formatters/export_formatter_tsv.hpp", "content/export_formatters/export_formatter_json.hpp", - "content/export_formatters/export_formatter.hpp", + "content/export_formatters/export_formatter_tsv.hpp", + "content/global_actions.hpp", + "content/helpers/constants.hpp", + "content/helpers/diagrams.hpp", + "content/popups/hex_editor/popup_hex_editor_base_address.hpp", + "content/popups/hex_editor/popup_hex_editor_decoded_string.hpp", + "content/popups/hex_editor/popup_hex_editor_fill.hpp", "content/popups/hex_editor/popup_hex_editor_find.hpp", + "content/popups/hex_editor/popup_hex_editor_goto.hpp", + "content/popups/hex_editor/popup_hex_editor_insert.hpp", + "content/popups/hex_editor/popup_hex_editor_page_size.hpp", + "content/popups/hex_editor/popup_hex_editor_paste_behaviour.hpp", + "content/popups/hex_editor/popup_hex_editor_remove.hpp", + "content/popups/hex_editor/popup_hex_editor_resize.hpp", + "content/popups/hex_editor/popup_hex_editor_select.hpp", "content/popups/popup_blocking_task.hpp", - "content/popups/popup_unsaved_changes.hpp", + "content/popups/popup_crash_recovered.hpp", "content/popups/popup_docs_question.hpp", "content/popups/popup_tasks_waiting.hpp", - "content/popups/popup_crash_recovered.hpp", - "content/text_highlighting/pattern_language.hpp", - "content/recent.hpp", - "content/global_actions.hpp", + "content/popups/popup_unsaved_changes.hpp", "content/providers/base64_provider.hpp", - "content/providers/gdb_provider.hpp", - "content/providers/view_provider.hpp", - "content/providers/process_memory_provider.hpp", + "content/providers/command_provider.hpp", "content/providers/disk_provider.hpp", + "content/providers/file_provider.hpp", + "content/providers/gdb_provider.hpp", + "content/providers/intel_hex_provider.hpp", + "content/providers/memory_file_provider.hpp", + "content/providers/motorola_srec_provider.hpp", "content/providers/null_provider.hpp", + "content/providers/process_memory_provider.hpp", "content/providers/udp_provider.hpp", - "content/providers/intel_hex_provider.hpp", + "content/providers/undo_operations/operation_bookmark.hpp", "content/providers/undo_operations/operation_insert.hpp", "content/providers/undo_operations/operation_remove.hpp", "content/providers/undo_operations/operation_write.hpp", - "content/providers/undo_operations/operation_bookmark.hpp", - "content/providers/motorola_srec_provider.hpp", - "content/providers/memory_file_provider.hpp", - "content/providers/file_provider.hpp", + "content/providers/view_provider.hpp", + "content/recent.hpp", + "content/text_highlighting/pattern_language.hpp", "content/tools_entries.hpp", - "content/helpers/diagrams.hpp", - "content/views/view_constants.hpp", - "content/views/view_theme_manager.hpp", - "content/views/view_about.hpp", "content/views/fullscreen/view_fullscreen_file_info.hpp", "content/views/fullscreen/view_fullscreen_save_editor.hpp", - "content/views/view_patches.hpp", - "content/views/view_tutorials.hpp", - "content/views/view_data_inspector.hpp", - "content/views/view_bookmarks.hpp", - "content/views/view_hex_editor.hpp", + "content/views/view_about.hpp", "content/views/view_achievements.hpp", - "content/views/view_tools.hpp", - "content/views/view_data_processor.hpp", + "content/views/view_bookmarks.hpp", "content/views/view_command_palette.hpp", - "content/views/view_settings.hpp", - "content/views/view_logs.hpp", + "content/views/view_data_inspector.hpp", + "content/views/view_data_processor.hpp", + "content/views/view_find.hpp", + "content/views/view_hex_editor.hpp", "content/views/view_highlight_rules.hpp", "content/views/view_information.hpp", + "content/views/view_logs.hpp", + "content/views/view_patches.hpp", + "content/views/view_pattern_data.hpp", "content/views/view_pattern_editor.hpp", - "content/views/view_find.hpp", "content/views/view_provider_settings.hpp", - "content/views/view_pattern_data.hpp", - "content/views/view_store.hpp ", - "content/command_line_interface.hpp", - "content/data_processor_nodes.hpp", - "content/differing_byte_searcher.hpp", + "content/views/view_settings.hpp", + "content/views/view_store.hpp", + "content/views/view_theme_manager.hpp", + "content/views/view_tools.hpp", + "content/views/view_tutorials.hpp", + "plugin_builtin.hpp", ] }, romfsdir="dep/r/imhex/plugins/builtin/romfs", diff --git a/src/gui2/configview.cc b/src/gui2/configview.cc index 7cadb02e..8c449668 100644 --- a/src/gui2/configview.cc +++ b/src/gui2/configview.cc @@ -382,3 +382,7 @@ void ConfigView::drawContent() } } } + +void ConfigView::drawHelpText() +{ +} diff --git a/src/gui2/configview.h b/src/gui2/configview.h index ec5fb3a1..d9bacd8f 100644 --- a/src/gui2/configview.h +++ b/src/gui2/configview.h @@ -9,6 +9,7 @@ class ConfigView : public hex::View::Window ~ConfigView() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { diff --git a/src/gui2/controlpanelview.cc b/src/gui2/controlpanelview.cc index 2f33fcbf..597f786d 100644 --- a/src/gui2/controlpanelview.cc +++ b/src/gui2/controlpanelview.cc @@ -157,3 +157,7 @@ void ControlPanelView::drawContent() Datastore::stop(); } } + +void ControlPanelView::drawHelpText() +{ +} diff --git a/src/gui2/controlpanelview.h b/src/gui2/controlpanelview.h index b67a2145..d53d5e93 100644 --- a/src/gui2/controlpanelview.h +++ b/src/gui2/controlpanelview.h @@ -9,6 +9,7 @@ class ControlPanelView : public hex::View::Window ~ControlPanelView() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { diff --git a/src/gui2/diskprovider.cc b/src/gui2/diskprovider.cc index 415aacef..6039245f 100644 --- a/src/gui2/diskprovider.cc +++ b/src/gui2/diskprovider.cc @@ -51,9 +51,9 @@ DiskProvider::~DiskProvider() return false; } -[[nodiscard]] bool DiskProvider::open() +[[nodiscard]] hex::prv::Provider::OpenResult DiskProvider::open() { - return true; + return OpenResult(); } void DiskProvider::close() {} diff --git a/src/gui2/diskprovider.h b/src/gui2/diskprovider.h index 6ed61067..e27d22d6 100644 --- a/src/gui2/diskprovider.h +++ b/src/gui2/diskprovider.h @@ -18,7 +18,7 @@ class DiskProvider : public hex::prv::Provider [[nodiscard]] bool isResizable() const override; [[nodiscard]] bool isSavable() const override; - [[nodiscard]] bool open() override; + [[nodiscard]] OpenResult open() override; void close() override; diff --git a/src/gui2/imhex_overrides/achievement_manager.cpp b/src/gui2/imhex_overrides/achievement_manager.cpp index c588f86a..1d7b39e8 100644 --- a/src/gui2/imhex_overrides/achievement_manager.cpp +++ b/src/gui2/imhex_overrides/achievement_manager.cpp @@ -8,4 +8,7 @@ namespace hex { } + void AchievementManager::loadProgress() + { + } } \ No newline at end of file diff --git a/src/gui2/imhex_overrides/imconfig.h b/src/gui2/imhex_overrides/imconfig.h index 0d4ce95a..4297e7bd 100644 --- a/src/gui2/imhex_overrides/imconfig.h +++ b/src/gui2/imhex_overrides/imconfig.h @@ -34,18 +34,17 @@ // while (0)' block so it can be used as a single statement. // #define IM_ASSERT(_EXPR) MyAssert(_EXPR) // #define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts -namespace hex::log::impl -{ - void assertionHandler(const char* expr_str, const char* file, int line); +namespace hex::dbg { + [[noreturn]] void assertionHandler(const char* file, int line, const char *function, const char* exprString); } -#define IM_ASSERT(_EXPR) \ - do \ - { \ - if (!(_EXPR)) [[unlikely]] \ - { \ - hex::log::impl::assertionHandler(#_EXPR, __FILE__, __LINE__); \ - } \ - } while (0) + +#if defined(__PRETTY_FUNCTION__) + #define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __PRETTY_FUNCTION__, #_EXPR); } } while(0) +#elif defined(__FUNCSIG__) + #define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __FUNCSIG__, #_EXPR); } } while(0) +#else + #define IM_ASSERT(_EXPR) do { if (!(_EXPR)) [[unlikely]] { hex::dbg::assertionHandler(__FILE__, __LINE__, __FUNCTION__, #_EXPR); } } while(0) +#endif //---- Define attributes of all API symbols declarations, e.g. for DLL under // Windows diff --git a/src/gui2/imhex_overrides/main_menu_items.cpp b/src/gui2/imhex_overrides/main_menu_items.cpp index 912fde82..80dd3b59 100644 --- a/src/gui2/imhex_overrides/main_menu_items.cpp +++ b/src/gui2/imhex_overrides/main_menu_items.cpp @@ -26,7 +26,6 @@ #include #include - #include #include @@ -39,615 +38,1094 @@ using namespace std::literals::string_literals; using namespace wolv::literals; -namespace hex::plugin::builtin { +namespace hex::plugin::builtin +{ - namespace { + namespace + { - bool noRunningTasks() { - return TaskManager::getRunningTaskCount() == 0; - } + bool noRunningTasks() + { return TaskManager::getRunningTaskCount() == 0; } - bool noRunningTaskAndValidProvider() { - return noRunningTasks() && ImHexApi::Provider::isValid(); - } + bool noRunningTaskAndValidProvider() + { return noRunningTasks() && ImHexApi::Provider::isValid(); } - bool noRunningTaskAndWritableProvider() { - return noRunningTasks() && ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isWritable(); + bool noRunningTaskAndWritableProvider() + { + return noRunningTasks() && ImHexApi::Provider::isValid() && + ImHexApi::Provider::get()->isWritable(); } } - namespace { - - void handleIPSError(IPSError error) { - TaskManager::doLater([error]{ - switch (error) { - case IPSError::InvalidPatchHeader: - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); - break; - case IPSError::AddressOutOfRange: - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); - break; - case IPSError::PatchTooLarge: - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); - break; - case IPSError::InvalidPatchFormat: - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); - break; - case IPSError::MissingEOF: - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); - break; - } - }); + namespace + { + + void handleIPSError(IPSError error) + { + TaskManager::doLater( + [error] + { + switch (error) + { + case IPSError::InvalidPatchHeader: + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); + break; + case IPSError::AddressOutOfRange: + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); + break; + case IPSError::PatchTooLarge: + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); + break; + case IPSError::InvalidPatchFormat: + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); + break; + case IPSError::MissingEOF: + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); + break; + } + }); } } // Import - namespace { - - void importIPSPatch() { - fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { - auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); - auto patch = Patches::fromIPSPatch(patchData); - if (!patch.has_value()) { - handleIPSError(patch.error()); - return; - } + namespace + { - task.setMaxValue(patch->get().size()); + void importIPSPatch() + { + fs::openFileBrowser(fs::DialogMode::Open, + {}, + [](const auto& path) + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [path](auto& task) + { + auto patchData = + wolv::io::File(path, wolv::io::File::Mode::Read) + .readVector(); + auto patch = Patches::fromIPSPatch(patchData); + if (!patch.has_value()) + { + handleIPSError(patch.error()); + return; + } - auto provider = ImHexApi::Provider::get(); + task.setMaxValue(patch->get().size()); - for (auto &[address, value] : patch->get()) { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + auto provider = ImHexApi::Provider::get(); + + for (auto& [address, value] : patch->get()) + { + provider->write(address, &value, sizeof(value)); + task.increment(); + } - provider->getUndoStack().groupOperations(patch->get().size(), "hex.builtin.undo_operation.patches"); + provider->getUndoStack().groupOperations( + patch->get().size(), + "hex.builtin.undo_operation.patches"); + }); }); - }); } - void importIPS32Patch() { - fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { - auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); - auto patch = Patches::fromIPS32Patch(patchData); - if (!patch.has_value()) { - handleIPSError(patch.error()); - return; - } + void importIPS32Patch() + { + fs::openFileBrowser(fs::DialogMode::Open, + {}, + [](const auto& path) + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [path](auto& task) + { + auto patchData = + wolv::io::File(path, wolv::io::File::Mode::Read) + .readVector(); + auto patch = Patches::fromIPS32Patch(patchData); + if (!patch.has_value()) + { + handleIPSError(patch.error()); + return; + } - task.setMaxValue(patch->get().size()); + task.setMaxValue(patch->get().size()); - auto provider = ImHexApi::Provider::get(); + auto provider = ImHexApi::Provider::get(); - for (auto &[address, value] : patch->get()) { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + for (auto& [address, value] : patch->get()) + { + provider->write(address, &value, sizeof(value)); + task.increment(); + } - provider->getUndoStack().groupOperations(patch->get().size(), "hex.builtin.undo_operation.patches"); + provider->getUndoStack().groupOperations( + patch->get().size(), + "hex.builtin.undo_operation.patches"); + }); }); - }); } - void importModifiedFile() { - fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { - auto provider = ImHexApi::Provider::get(); - auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); - - if (patchData.size() != provider->getActualSize()) { - ui::ToastError::open("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); - return; - } + void importModifiedFile() + { + fs::openFileBrowser(fs::DialogMode::Open, + {}, + [](const auto& path) + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [path](auto& task) + { + auto provider = ImHexApi::Provider::get(); + auto patchData = + wolv::io::File(path, wolv::io::File::Mode::Read) + .readVector(); + + if (patchData.size() != provider->getActualSize()) + { + ui::ToastError::open( + "hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); + return; + } - const auto baseAddress = provider->getBaseAddress(); + const auto baseAddress = provider->getBaseAddress(); - std::map patches; - for (u64 i = 0; i < patchData.size(); i++) { - u8 value = 0; - provider->read(baseAddress + i, &value, 1); + std::map patches; + for (u64 i = 0; i < patchData.size(); i++) + { + u8 value = 0; + provider->read(baseAddress + i, &value, 1); - if (value != patchData[i]) - patches[baseAddress + i] = patchData[i]; - } + if (value != patchData[i]) + patches[baseAddress + i] = patchData[i]; + } - task.setMaxValue(patches.size()); + task.setMaxValue(patches.size()); - for (auto &[address, value] : patches) { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + for (auto& [address, value] : patches) + { + provider->write(address, &value, sizeof(value)); + task.increment(); + } - provider->getUndoStack().groupOperations(patches.size(), "hex.builtin.undo_operation.patches"); + provider->getUndoStack().groupOperations( + patches.size(), + "hex.builtin.undo_operation.patches"); + }); }); - }); } } // Export - namespace { - - void exportBase64() { - fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &) { - wolv::io::File outputFile(path, wolv::io::File::Mode::Create); - if (!outputFile.isValid()) { - TaskManager::doLater([] { - ui::ToastError::open("hex.builtin.menu.file.export.error.create_file"_lang); - }); - return; - } + namespace + { - auto provider = ImHexApi::Provider::get(); - std::vector bytes(5_MiB); - for (u64 address = 0; address < provider->getActualSize(); address += bytes.size()) { - bytes.resize(std::min(bytes.size(), provider->getActualSize() - address)); - provider->read(provider->getBaseAddress() + address, bytes.data(), bytes.size()); + void exportBase64() + { + fs::openFileBrowser(fs::DialogMode::Save, + {}, + [](const auto& path) + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [path](auto&) + { + wolv::io::File outputFile( + path, wolv::io::File::Mode::Create); + if (!outputFile.isValid()) + { + TaskManager::doLater( + [] + { + ui::ToastError::open( + "hex.builtin.menu.file.export.error.create_file"_lang); + }); + return; + } - outputFile.writeVector(crypt::encode64(bytes)); - } + auto provider = ImHexApi::Provider::get(); + std::vector bytes(5_MiB); + for (u64 address = 0; + address < provider->getActualSize(); + address += bytes.size()) + { + bytes.resize(std::min(bytes.size(), + provider->getActualSize() - address)); + provider->read( + provider->getBaseAddress() + address, + bytes.data(), + bytes.size()); + + outputFile.writeVector(crypt::encode64(bytes)); + } + }); }); - }); } - void exportSelectionToFile() { - fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { - wolv::io::File outputFile(path, wolv::io::File::Mode::Create); - if (!outputFile.isValid()) { - TaskManager::doLater([] { - ui::ToastError::open("hex.builtin.menu.file.export.error.create_file"_lang); - }); - return; - } - - auto provider = ImHexApi::Provider::get(); - std::vector bytes(5_MiB); - - auto selection = ImHexApi::HexEditor::getSelection(); - for (u64 address = selection->getStartAddress(); address <= selection->getEndAddress(); address += bytes.size()) { - bytes.resize(std::min(bytes.size(), selection->getEndAddress() - address + 1)); - provider->read(address, bytes.data(), bytes.size()); + void exportSelectionToFile() + { + fs::openFileBrowser(fs::DialogMode::Save, + {}, + [](const auto& path) + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [path](auto& task) + { + wolv::io::File outputFile( + path, wolv::io::File::Mode::Create); + if (!outputFile.isValid()) + { + TaskManager::doLater( + [] + { + ui::ToastError::open( + "hex.builtin.menu.file.export.error.create_file"_lang); + }); + return; + } - outputFile.writeVector(bytes); - task.update(); - } + auto provider = ImHexApi::Provider::get(); + std::vector bytes(5_MiB); + + auto selection = + ImHexApi::HexEditor::getSelection(); + for (u64 address = selection->getStartAddress(); + address <= selection->getEndAddress(); + address += bytes.size()) + { + bytes.resize(std::min(bytes.size(), + selection->getEndAddress() - address + 1)); + provider->read( + address, bytes.data(), bytes.size()); + + outputFile.writeVector(bytes); + task.update(); + } + }); }); - }); } - void drawExportLanguageMenu() { - for (const auto &formatter : ContentRegistry::DataFormatter::impl::getExportMenuEntries()) { - if (menu::menuItem(Lang(formatter.unlocalizedName), Shortcut::None, false, ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->getActualSize() > 0)) { - fs::openFileBrowser(fs::DialogMode::Save, {}, [&formatter](const auto &path) { - TaskManager::createTask("hex.builtin.task.exporting_data", TaskManager::NoProgress, [&formatter, path](auto&){ - auto provider = ImHexApi::Provider::get(); - auto selection = ImHexApi::HexEditor::getSelection() - .value_or( - ImHexApi::HexEditor::ProviderRegion { - { provider->getBaseAddress(), provider->getSize() }, - provider + void drawExportLanguageMenu() + { + for (const auto& formatter : + ContentRegistry::DataFormatter::impl::getExportMenuEntries()) + { + if (menu::menuItem(Lang(formatter.unlocalizedName), + Shortcut::None, + false, + ImHexApi::Provider::isValid() && + ImHexApi::Provider::get()->getActualSize() > 0)) + { + fs::openFileBrowser(fs::DialogMode::Save, + {}, + [&formatter](const auto& path) + { + TaskManager::createTask( + "hex.builtin.task.exporting_data", + TaskManager::NoProgress, + [&formatter, path](auto&) + { + auto provider = ImHexApi::Provider::get(); + auto selection = + ImHexApi::HexEditor::getSelection() + .value_or(ImHexApi::HexEditor:: + ProviderRegion{ + {provider + ->getBaseAddress(), + provider + ->getSize()}, + provider + }); + + auto result = formatter.callback(provider, + selection.getStartAddress(), + selection.getSize(), + false); + + wolv::io::File file( + path, wolv::io::File::Mode::Create); + if (!file.isValid()) + { + TaskManager::doLater( + [] + { + ui::ToastError::open( + "hex.builtin.menu.file.export.as_language.popup.export_error"_lang); }); + return; + } - auto result = formatter.callback(provider, selection.getStartAddress(), selection.getSize(), false); - - wolv::io::File file(path, wolv::io::File::Mode::Create); - if (!file.isValid()) { - TaskManager::doLater([] { - ui::ToastError::open("hex.builtin.menu.file.export.as_language.popup.export_error"_lang); + file.writeString(result); }); - return; - } - - file.writeString(result); }); - }); } } } - void exportReport() { - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [](auto &) { - std::string data; - - for (const auto &provider : ImHexApi::Provider::getProviders()) { - data += fmt::format("# {}", provider->getName()); - data += "\n\n"; - - for (const auto &generator : ContentRegistry::Reports::impl::getGenerators()) { - data += generator.callback(provider); + void exportReport() + { + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [](auto&) + { + std::string data; + + for (const auto& provider : + ImHexApi::Provider::getProviders()) + { + data += fmt::format("# {}", provider->getName()); data += "\n\n"; - } - data += "\n\n"; - } - TaskManager::doLater([data] { - fs::openFileBrowser(fs::DialogMode::Save, { { "Markdown File", "md" }}, [&data](const auto &path) { - auto file = wolv::io::File(path, wolv::io::File::Mode::Create); - if (!file.isValid()) { - ui::ToastError::open("hex.builtin.menu.file.export.report.popup.export_error"_lang); - return; + for (const auto& generator : + ContentRegistry::Reports::impl::getGenerators()) + { + data += generator.callback(provider); + data += "\n\n"; } + data += "\n\n"; + } - file.writeString(data); - }); + TaskManager::doLater( + [data] + { + fs::openFileBrowser(fs::DialogMode::Save, + { + {"Markdown File", "md"} + }, + [&data](const auto& path) + { + auto file = wolv::io::File( + path, wolv::io::File::Mode::Create); + if (!file.isValid()) + { + ui::ToastError::open( + "hex.builtin.menu.file.export.report.popup.export_error"_lang); + return; + } + + file.writeString(data); + }); + }); }); - }); } - void exportIPSPatch() { + void exportIPSPatch() + { auto provider = ImHexApi::Provider::get(); auto patches = Patches::fromProvider(provider); - if (!patches.has_value()) { + if (!patches.has_value()) + { handleIPSError(patches.error()); return; } - // Make sure there's no patch at address 0x00454F46 because that would cause the patch to contain the sequence "EOF" which signals the end of the patch - if (!patches->get().contains(0x00454F45) && patches->get().contains(0x00454F46)) { + // Make sure there's no patch at address 0x00454F46 because that + // would cause the patch to contain the sequence "EOF" which signals + // the end of the patch + if (!patches->get().contains(0x00454F45) && + patches->get().contains(0x00454F46)) + { u8 value = 0; provider->read(0x00454F45, &value, sizeof(u8)); patches->get().at(0x00454F45) = value; } - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [patches](auto &) { - auto data = patches->toIPSPatch(); - - TaskManager::doLater([data] { - fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { - auto file = wolv::io::File(path, wolv::io::File::Mode::Create); - if (!file.isValid()) { - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); - return; - } - - if (data.has_value()) { - const auto& bytes = data.value(); - file.writeVector(bytes); - EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS); - } else { - handleIPSError(data.error()); - } - }); + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [patches](auto&) + { + auto data = patches->toIPSPatch(); + + TaskManager::doLater( + [data] + { + fs::openFileBrowser(fs::DialogMode::Save, + {}, + [&data](const auto& path) + { + auto file = wolv::io::File( + path, wolv::io::File::Mode::Create); + if (!file.isValid()) + { + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.export_error"_lang); + return; + } + + if (data.has_value()) + { + const auto& bytes = data.value(); + file.writeVector(bytes); + EventPatchCreated::post(bytes.data(), + bytes.size(), + PatchKind::IPS); + } + else + { + handleIPSError(data.error()); + } + }); + }); }); - }); } - void exportIPS32Patch() { + void exportIPS32Patch() + { auto provider = ImHexApi::Provider::get(); auto patches = Patches::fromProvider(provider); - if (!patches.has_value()) { + if (!patches.has_value()) + { handleIPSError(patches.error()); return; } - // Make sure there's no patch at address 0x45454F46 because that would cause the patch to contain the sequence "*EOF" which signals the end of the patch - if (!patches->get().contains(0x45454F45) && patches->get().contains(0x45454F46)) { + // Make sure there's no patch at address 0x45454F46 because that + // would cause the patch to contain the sequence "*EOF" which + // signals the end of the patch + if (!patches->get().contains(0x45454F45) && + patches->get().contains(0x45454F46)) + { u8 value = 0; provider->read(0x45454F45, &value, sizeof(u8)); patches->get().at(0x45454F45) = value; } - TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [patches](auto &) { - auto data = patches->toIPS32Patch(); - - TaskManager::doLater([data] { - fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { - auto file = wolv::io::File(path, wolv::io::File::Mode::Create); - if (!file.isValid()) { - ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); - return; - } - - if (data.has_value()) { - const std::vector& bytes = data.value(); - file.writeVector(bytes); - EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS32); - } else { - handleIPSError(data.error()); - } - }); + TaskManager::createTask("hex.ui.common.processing", + TaskManager::NoProgress, + [patches](auto&) + { + auto data = patches->toIPS32Patch(); + + TaskManager::doLater( + [data] + { + fs::openFileBrowser(fs::DialogMode::Save, + {}, + [&data](const auto& path) + { + auto file = wolv::io::File( + path, wolv::io::File::Mode::Create); + if (!file.isValid()) + { + ui::ToastError::open( + "hex.builtin.menu.file.export.ips.popup.export_error"_lang); + return; + } + + if (data.has_value()) + { + const std::vector& bytes = + data.value(); + file.writeVector(bytes); + EventPatchCreated::post(bytes.data(), + bytes.size(), + PatchKind::IPS32); + } + else + { + handleIPSError(data.error()); + } + }); + }); }); - }); } } - /** - * @brief returns true if there is a currently selected provider, and it is possibl to dump data from it + * @brief returns true if there is a currently selected provider, and it is + * possibl to dump data from it */ - bool isProviderDumpable() { + bool isProviderDumpable() + { auto provider = ImHexApi::Provider::get(); return ImHexApi::Provider::isValid() && provider->isDumpable(); } - static void createFileMenu() { + static void createFileMenu() + { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.file", 1000); + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.file", 1000); /* Create File */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.create_file" }, ICON_VS_FILE, 1050, CTRLCMD + Keys::N + AllowWhileTyping, [] { - auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true); - if (newProvider != nullptr && !newProvider->open()) - hex::ImHexApi::Provider::remove(newProvider); - else - EventProviderOpened::post(newProvider); - }, noRunningTasks); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", "hex.builtin.menu.file.create_file"}, + ICON_VS_FILE, + 1050, + CTRLCMD + Keys::N + AllowWhileTyping, + [] + { + auto newProvider = hex::ImHexApi::Provider::createProvider( + "hex.builtin.provider.mem_file", true); + if (newProvider != nullptr && newProvider->open().isFailure()) + hex::ImHexApi::Provider::remove(newProvider.get()); + else + EventProviderOpened::post(newProvider.get()); + }, + noRunningTasks); /* Open File */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.open_file" }, ICON_VS_FOLDER_OPENED, 1100, CTRLCMD + Keys::O + AllowWhileTyping + ShowOnWelcomeScreen, [] { - RequestOpenWindow::post("Open File"); - }, noRunningTasks, ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name")); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", "hex.builtin.menu.file.open_file"}, + ICON_VS_FOLDER_OPENED, + 1100, + CTRLCMD + Keys::O + AllowWhileTyping + ShowOnWelcomeScreen, + [] + { + RequestOpenWindow::post("Open File"); + }, + noRunningTasks, + ContentRegistry::Views::getViewByName( + "hex.builtin.view.hex_editor.name")); /* Open Other */ - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.open_other"}, ICON_VS_TELESCOPE, 1150, [] { - for (const auto &[unlocalizedProviderName, icon] : ContentRegistry::Provider::impl::getEntries()) { - if (menu::menuItemEx(Lang(unlocalizedProviderName), icon)) - ImHexApi::Provider::createProvider(unlocalizedProviderName); - } - }, noRunningTasks); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.file", "hex.builtin.menu.file.open_other"}, + ICON_VS_TELESCOPE, + 1150, + [] + { + for (const auto& [unlocalizedProviderName, icon] : + ContentRegistry::Provider::impl::getEntries()) + { + if (menu::menuItemEx(Lang(unlocalizedProviderName), icon)) + ImHexApi::Provider::createProvider( + unlocalizedProviderName); + } + }, + noRunningTasks); /* Reload Provider */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.reload_provider"}, ICON_VS_REFRESH, 1250, CTRLCMD + Keys::R + AllowWhileTyping, [] { - auto provider = ImHexApi::Provider::get(); - - provider->close(); - if (!provider->open()) - ImHexApi::Provider::remove(provider, true); - - EventDataChanged::post(provider); - }, noRunningTaskAndValidProvider); - + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", "hex.builtin.menu.file.reload_provider"}, + ICON_VS_REFRESH, + 1250, + CTRLCMD + Keys::R + AllowWhileTyping, + [] + { + auto provider = ImHexApi::Provider::get(); + + provider->close(); + if (provider->open().isFailure()) + ImHexApi::Provider::remove(provider, true); + + EventDataChanged::post(provider); + }, + noRunningTaskAndValidProvider); /* Project open / save */ - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.project" }, ICON_VS_NOTEBOOK, 1400, []{}, noRunningTasks); - - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.open" }, ICON_VS_ROOT_FOLDER_OPENED, 1410, - CTRL + ALT + Keys::O + AllowWhileTyping, - openProject, noRunningTasks); - - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save" }, ICON_VS_SAVE, 1450, - CTRL + ALT + Keys::S + AllowWhileTyping, - saveProject, [&] { return noRunningTaskAndValidProvider() && ProjectFile::hasPath(); }); - - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save_as" }, ICON_VS_SAVE_AS, 1500, - ALT + SHIFT + Keys::S + AllowWhileTyping, - saveProjectAs, noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.file", "hex.builtin.menu.file.project"}, + ICON_VS_NOTEBOOK, + 1400, + [] + { + }, + noRunningTasks); + + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.project", + "hex.builtin.menu.file.project.open"}, + ICON_VS_ROOT_FOLDER_OPENED, + 1410, + CTRL + ALT + Keys::O + AllowWhileTyping, + openProject, + noRunningTasks); + + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.project", + "hex.builtin.menu.file.project.save"}, + ICON_VS_SAVE, + 1450, + CTRL + ALT + Keys::S + AllowWhileTyping, + saveProject, + [&] + { + return noRunningTaskAndValidProvider() && + ProjectFile::hasPath(); + }); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.project", + "hex.builtin.menu.file.project.save_as"}, + ICON_VS_SAVE_AS, + 1500, + ALT + SHIFT + Keys::S + AllowWhileTyping, + saveProjectAs, + noRunningTaskAndValidProvider); - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 2000); + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.file"}, 2000); /* Import */ { - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.import" }, ICON_VS_SIGN_IN, 5140, []{}, noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.file", "hex.builtin.menu.file.import"}, + ICON_VS_SIGN_IN, + 5140, + [] + { + }, + noRunningTaskAndValidProvider); /* IPS */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5150, - Shortcut::None, - importIPSPatch, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.import", + "hex.builtin.menu.file.import.ips"}, + ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, + 5150, + Shortcut::None, + importIPSPatch, + noRunningTaskAndWritableProvider); /* IPS32 */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips32"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5200, - Shortcut::None, - importIPS32Patch, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.import", + "hex.builtin.menu.file.import.ips32"}, + ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, + 5200, + Shortcut::None, + importIPS32Patch, + noRunningTaskAndWritableProvider); /* Modified File */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.modified_file" }, ICON_VS_FILES, 5300, - Shortcut::None, - importModifiedFile, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.import", + "hex.builtin.menu.file.import.modified_file"}, + ICON_VS_FILES, + 5300, + Shortcut::None, + importModifiedFile, + noRunningTaskAndWritableProvider); } /* Export */ /* Only make them accessible if the current provider is dumpable */ { - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, ICON_VS_SIGN_OUT, 6000, []{}, isProviderDumpable); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.file", "hex.builtin.menu.file.export"}, + ICON_VS_SIGN_OUT, + 6000, + [] + { + }, + isProviderDumpable); /* Selection to File */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.selection_to_file" }, ICON_VS_FILE_BINARY, 6010, - Shortcut::None, - exportSelectionToFile, - ImHexApi::HexEditor::isSelectionValid); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.selection_to_file"}, + ICON_VS_FILE_BINARY, + 6010, + Shortcut::None, + exportSelectionToFile, + ImHexApi::HexEditor::isSelectionValid); /* Base 64 */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.base64" }, ICON_VS_NOTE, 6020, - Shortcut::None, - exportBase64, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.base64"}, + ICON_VS_NOTE, + 6020, + Shortcut::None, + exportBase64, + isProviderDumpable); /* Language */ - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.as_language" }, ICON_VS_CODE, 6030, - drawExportLanguageMenu, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.as_language"}, + ICON_VS_CODE, + 6030, + drawExportLanguageMenu, + isProviderDumpable); /* Report */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.report" }, ICON_VS_MARKDOWN, 6040, - Shortcut::None, - exportReport, - ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, 6050); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.report"}, + ICON_VS_MARKDOWN, + 6040, + Shortcut::None, + exportReport, + ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.file", "hex.builtin.menu.file.export"}, + 6050); /* IPS */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6100, - Shortcut::None, - exportIPSPatch, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.ips"}, + ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, + 6100, + Shortcut::None, + exportIPSPatch, + isProviderDumpable); /* IPS32 */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips32" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6150, - Shortcut::None, - exportIPS32Patch, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", + "hex.builtin.menu.file.export", + "hex.builtin.menu.file.export.ips32"}, + ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, + 6150, + Shortcut::None, + exportIPS32Patch, + isProviderDumpable); } - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 10000); + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.file"}, 10000); /* Close Provider */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.close"}, ICON_VS_CHROME_CLOSE, 10050, CTRLCMD + Keys::W + AllowWhileTyping, [] { - ImHexApi::Provider::remove(ImHexApi::Provider::get()); - }, noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", "hex.builtin.menu.file.close"}, + ICON_VS_CHROME_CLOSE, + 10050, + CTRLCMD + Keys::W + AllowWhileTyping, + [] + { + ImHexApi::Provider::remove(ImHexApi::Provider::get()); + }, + noRunningTaskAndValidProvider); /* Quit ImHex */ - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.quit"}, ICON_VS_CLOSE_ALL, 10100, ALT + Keys::F4 + AllowWhileTyping, [] { - ImHexApi::System::closeImHex(); - }); + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.file", "hex.builtin.menu.file.quit"}, + ICON_VS_CLOSE_ALL, + 10100, + ALT + Keys::F4 + AllowWhileTyping, + [] + { + ImHexApi::System::closeImHex(); + }); } - static void createEditMenu() { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.edit", 2000); + static void createEditMenu() + { + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.edit", 2000); } - static void createViewMenu() { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.view", 3000); - - #if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top" }, ICON_VS_PINNED, 1000, Keys::F10 + AllowWhileTyping, [] { + static void createViewMenu() + { + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.view", 3000); + +#if !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top"}, + ICON_VS_PINNED, + 1000, + Keys::F10 + AllowWhileTyping, + [] + { static bool state = false; state = !state; - glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING, state); - }, []{ return true; }, []{ return glfwGetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); }); - #endif - - #if !defined(OS_MACOS) && !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen" }, ICON_VS_SCREEN_FULL, 2000, Keys::F11 + AllowWhileTyping, [] { + glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), + GLFW_FLOATING, + state); + }, + [] + { + return true; + }, + [] + { + return glfwGetWindowAttrib( + ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); + }); +#endif + +#if !defined(OS_MACOS) && !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen"}, + ICON_VS_SCREEN_FULL, + 2000, + Keys::F11 + AllowWhileTyping, + [] + { static bool state = false; static ImVec2 position, size; state = !state; - const auto window = ImHexApi::System::getMainWindowHandle(); - if (state) { + if (state) + { position = ImHexApi::System::getMainWindowPosition(); - size = ImHexApi::System::getMainWindowSize(); + size = ImHexApi::System::getMainWindowSize(); const auto monitor = glfwGetPrimaryMonitor(); const auto videoMode = glfwGetVideoMode(monitor); - glfwSetWindowMonitor(window, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); - } else { - glfwSetWindowMonitor(window, nullptr, position.x, position.y, size.x, size.y, 0); - glfwSetWindowAttrib(window, GLFW_DECORATED, ImHexApi::System::isBorderlessWindowModeEnabled() ? GLFW_FALSE : GLFW_TRUE); + glfwSetWindowMonitor(window, + monitor, + 0, + 0, + videoMode->width, + videoMode->height, + videoMode->refreshRate); } - - }, []{ return true; }, []{ return glfwGetWindowMonitor(ImHexApi::System::getMainWindowHandle()) != nullptr; }); - #endif - - #if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.view" }, 3000); - #endif - - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.view" }, 4000, [] { - for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) { - if (view->hasViewMenuItemEntry()) { - auto &state = view->getWindowOpenState(); - - if (menu::menuItemEx(Lang(view->getUnlocalizedName()), view->getIcon(), Shortcut::None, state, ImHexApi::Provider::isValid() && !LayoutManager::isLayoutLocked())) - state = !state; + else + { + glfwSetWindowMonitor(window, + nullptr, + position.x, + position.y, + size.x, + size.y, + 0); + glfwSetWindowAttrib(window, + GLFW_DECORATED, + ImHexApi::System::isBorderlessWindowModeEnabled() + ? GLFW_FALSE + : GLFW_TRUE); } - } - }); - + }, + [] + { + return true; + }, + [] + { + return glfwGetWindowMonitor( + ImHexApi::System::getMainWindowHandle()) != nullptr; + }); +#endif + +#if !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.view"}, 3000); +#endif + + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.view"}, + 4000, + [] + { + for (auto& [name, view] : + ContentRegistry::Views::impl::getEntries()) + { + if (view->hasViewMenuItemEntry()) + { + auto& state = view->getWindowOpenState(); + + if (menu::menuItemEx(Lang(view->getUnlocalizedName()), + view->getIcon(), + Shortcut::None, + state, + ImHexApi::Provider::isValid() && + !LayoutManager::isLayoutLocked())) + state = !state; + } + } + }); } - static void createLayoutMenu() { + static void createLayoutMenu() + { LayoutManager::reload(); - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, ICON_VS_LAYOUT, 1050, []{}, ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout", "hex.builtin.menu.workspace.layout.save" }, 1100, Shortcut::None, [] { - ui::PopupTextInput::open("hex.builtin.popup.save_layout.title", "hex.builtin.popup.save_layout.desc", [](const std::string &name) { - LayoutManager::save(name); + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, + ICON_VS_LAYOUT, + 1050, + [] + { + }, + ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.workspace", + "hex.builtin.menu.workspace.layout", + "hex.builtin.menu.workspace.layout.save"}, + 1100, + Shortcut::None, + [] + { + ui::PopupTextInput::open("hex.builtin.popup.save_layout.title", + "hex.builtin.popup.save_layout.desc", + [](const std::string& name) + { + LayoutManager::save(name); + }); + }, + ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, + ICON_VS_LAYOUT, + 1150, + [] + { + bool locked = LayoutManager::isLayoutLocked(); + if (menu::menuItemEx( + "hex.builtin.menu.workspace.layout.lock"_lang, + ICON_VS_LOCK, + Shortcut::None, + locked, + ImHexApi::Provider::isValid())) + { + LayoutManager::lockLayout(!locked); + ContentRegistry::Settings::write( + "hex.builtin.setting.interface", + "hex.builtin.setting.interface.layout_locked", + !locked); + } }); - }, ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, ICON_VS_LAYOUT, 1150, [] { - bool locked = LayoutManager::isLayoutLocked(); - if (menu::menuItemEx("hex.builtin.menu.workspace.layout.lock"_lang, ICON_VS_LOCK, Shortcut::None, locked, ImHexApi::Provider::isValid())) { - LayoutManager::lockLayout(!locked); - ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.layout_locked", !locked); - } - }); - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 1200); - - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 2000, [] { - for (const auto &path : romfs::list("layouts")) { - if (menu::menuItem(wolv::util::capitalizeString(path.stem().string()).c_str(), Shortcut::None, false, ImHexApi::Provider::isValid())) { - LayoutManager::loadFromString(std::string(romfs::get(path).string())); + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, + 1200); + + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, + 2000, + [] + { + for (const auto& path : romfs::list("layouts")) + { + if (menu::menuItem( + wolv::util::capitalizeString(path.stem().string()) + .c_str(), + Shortcut::None, + false, + ImHexApi::Provider::isValid())) + { + LayoutManager::loadFromString( + std::string(romfs::get(path).string())); + } } - } - bool shiftPressed = ImGui::GetIO().KeyShift; - for (auto &[name, path] : LayoutManager::getLayouts()) { - if (menu::menuItem(fmt::format("{}{}", name, shiftPressed ? " " ICON_VS_CHROME_CLOSE : "").c_str(), Shortcut::None, false, ImHexApi::Provider::isValid())) { - if (shiftPressed) { - LayoutManager::removeLayout(name); - break; - } else { - LayoutManager::load(path); + bool shiftPressed = ImGui::GetIO().KeyShift; + for (auto& [name, path] : LayoutManager::getLayouts()) + { + if (menu::menuItem( + fmt::format("{}{}", + name, + shiftPressed ? " " ICON_VS_CHROME_CLOSE : "") + .c_str(), + Shortcut::None, + false, + ImHexApi::Provider::isValid())) + { + if (shiftPressed) + { + LayoutManager::removeLayout(name); + break; + } + else + { + LayoutManager::load(path); + } } } - } - }); + }); } - static void createWorkspaceMenu() { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.workspace", 4000); + static void createWorkspaceMenu() + { + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.workspace", 4000); createLayoutMenu(); - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.workspace" }, 3000); - - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.create" }, ICON_VS_ADD, 3100, Shortcut::None, [] { - ui::PopupTextInput::open("hex.builtin.popup.create_workspace.title", "hex.builtin.popup.create_workspace.desc", [](const std::string &name) { - WorkspaceManager::createWorkspace(name); - }); - }, ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace" }, 3200, [] { - const auto &workspaces = WorkspaceManager::getWorkspaces(); - - bool shiftPressed = ImGui::GetIO().KeyShift; - for (auto it = workspaces.begin(); it != workspaces.end(); ++it) { - const auto &[name, workspace] = *it; - - bool canRemove = shiftPressed && !workspace.builtin; - if (menu::menuItem(fmt::format("{}{}", name, canRemove ? " " ICON_VS_CHROME_CLOSE : "").c_str(), Shortcut::None, it == WorkspaceManager::getCurrentWorkspace(), ImHexApi::Provider::isValid())) { - if (canRemove) { - WorkspaceManager::removeWorkspace(name); - break; - } else { - WorkspaceManager::switchWorkspace(name); + ContentRegistry::UserInterface::addMenuItemSeparator( + {"hex.builtin.menu.workspace"}, 3000); + + ContentRegistry::UserInterface::addMenuItem( + {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.create"}, + ICON_VS_ADD, + 3100, + Shortcut::None, + [] + { + ui::PopupTextInput::open( + "hex.builtin.popup.create_workspace.title", + "hex.builtin.popup.create_workspace.desc", + [](const std::string& name) + { + WorkspaceManager::createWorkspace(name); + }); + }, + ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItemSubMenu( + {"hex.builtin.menu.workspace"}, + 3200, + [] + { + const auto& workspaces = WorkspaceManager::getWorkspaces(); + + bool shiftPressed = ImGui::GetIO().KeyShift; + for (auto it = workspaces.begin(); it != workspaces.end(); ++it) + { + const auto& [name, workspace] = *it; + + bool canRemove = shiftPressed && !workspace.builtin; + if (menu::menuItem( + fmt::format("{}{}", + name, + canRemove ? " " ICON_VS_CHROME_CLOSE : "") + .c_str(), + Shortcut::None, + it == WorkspaceManager::getCurrentWorkspace(), + ImHexApi::Provider::isValid())) + { + if (canRemove) + { + WorkspaceManager::removeWorkspace(name); + break; + } + else + { + WorkspaceManager::switchWorkspace(name); + } } } - } - }); + }); } - static void createExtrasMenu() { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.extras", 5000); + static void createExtrasMenu() + { + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.extras", 5000); } - static void createHelpMenu() { - ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.help", 6000); + static void createHelpMenu() + { + ContentRegistry::UserInterface::registerMainMenuItem( + "hex.builtin.menu.help", 6000); } - - void registerMainMenuEntries() { + void registerMainMenuEntries() + { createFileMenu(); createEditMenu(); createViewMenu(); diff --git a/src/gui2/imhex_overrides/menu_items.cpp b/src/gui2/imhex_overrides/menu_items.cpp index 3f3a289f..f02b2602 100644 --- a/src/gui2/imhex_overrides/menu_items.cpp +++ b/src/gui2/imhex_overrides/menu_items.cpp @@ -97,6 +97,21 @@ namespace hex::menu { ImGui::EndMenu(); } + bool beginTaskBarMenu() { + #if defined(OS_MACOS) + return beginMenu(ContentRegistry::UserInterface::impl::TaskBarMenuValue, true); + #else + return false; + #endif + } + + void endTaskBarMenu() { + #if defined(OS_MACOS) + endMenu(); + #else + + #endif + } bool menuItem(const char *label, const Shortcut &shortcut, bool selected, bool enabled) { #if defined(OS_MACOS) diff --git a/src/gui2/imhex_overrides/providers.cpp b/src/gui2/imhex_overrides/providers.cpp index 6b0db871..f8e93cd2 100644 --- a/src/gui2/imhex_overrides/providers.cpp +++ b/src/gui2/imhex_overrides/providers.cpp @@ -22,97 +22,142 @@ #include -namespace hex::plugin::builtin { +namespace hex::plugin::builtin +{ - void registerProviders() { + void registerProviders() + { ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); - ProjectFile::registerHandler({ - .basePath = "providers", + ProjectFile::registerHandler({.basePath = "providers", .required = true, - .load = [](const std::fs::path &basePath, const Tar &tar) { - auto json = nlohmann::json::parse(tar.readString(basePath / "providers.json")); + .load = + [](const std::fs::path& basePath, const Tar& tar) + { + auto json = nlohmann::json::parse( + tar.readString(basePath / "providers.json")); auto providerIds = json.at("providers").get>(); bool success = true; - std::map providerWarnings; - for (const auto &id : providerIds) { - auto providerSettings = nlohmann::json::parse(tar.readString(basePath / fmt::format("{}.json", id))); - - auto providerType = providerSettings.at("type").get(); - auto newProvider = ImHexApi::Provider::createProvider(providerType, true, false); - ON_SCOPE_EXIT { - if (!success) { - for (auto &task : TaskManager::getRunningTasks()) + std::map, std::string> + providerWarnings; + for (const auto& id : providerIds) + { + auto providerSettings = nlohmann::json::parse( + tar.readString(basePath / fmt::format("{}.json", id))); + + auto providerType = + providerSettings.at("type").get(); + auto newProvider = ImHexApi::Provider::createProvider( + providerType, true, false); + ON_SCOPE_EXIT + { + if (!success) + { + for (auto& task : TaskManager::getRunningTasks()) task->interrupt(); - TaskManager::runWhenTasksFinished([]{ - for (const auto &provider : ImHexApi::Provider::getProviders()) - ImHexApi::Provider::remove(provider, true); - }); + TaskManager::runWhenTasksFinished( + [] + { + for (const auto& provider : + ImHexApi::Provider::getProviders()) + ImHexApi::Provider::remove( + provider, true); + }); } }; - if (newProvider == nullptr) { - // If a provider is not created, it will be overwritten when saving the project, - // so we should prevent the project from loading at all - ui::ToastError::open( - fmt::format("hex.builtin.popup.error.project.load"_lang, - fmt::format("hex.builtin.popup.error.project.load.create_provider"_lang, providerType) - ) - ); + if (newProvider == nullptr) + { + // If a provider is not created, it will be overwritten + // when saving the project, so we should prevent the + // project from loading at all + ui::ToastError::open(fmt::format( + "hex.builtin.popup.error.project.load"_lang, + fmt::format( + "hex.builtin.popup.error.project.load.create_provider"_lang, + providerType))); success = false; break; } newProvider->setID(id); bool loaded = false; - try { - newProvider->loadSettings(providerSettings.at("settings")); + try + { + newProvider->loadSettings( + providerSettings.at("settings")); loaded = true; - } catch (const std::exception &e){ - providerWarnings[newProvider] = e.what(); } - if (loaded) { - if (!newProvider->open() || !newProvider->isAvailable() || !newProvider->isReadable()) { - providerWarnings[newProvider] = newProvider->getErrorMessage(); - } else { - EventProviderOpened::post(newProvider); + catch (const std::exception& e) + { + providerWarnings[newProvider] = e.what(); + } + if (loaded) + { + auto openResult = newProvider->open(); + if (openResult.isFailure() || + !newProvider->isAvailable() || + !newProvider->isReadable()) + { + providerWarnings[newProvider] = + openResult.getErrorMessage(); + } + else + { + EventProviderOpened::post(newProvider.get()); } } } std::string warningMessage; - for (const auto &warning : providerWarnings){ - ImHexApi::Provider::remove(warning.first); - warningMessage.append( - fmt::format("\n - {} : {}", warning.first->getName(), warning.second)); + for (const auto& warning : providerWarnings) + { + ImHexApi::Provider::remove(warning.first.get()); + warningMessage.append(fmt::format("\n - {} : {}", + warning.first->getName(), + warning.second)); } // If no providers were opened, display an error with - // the warnings that happened when opening them - if (ImHexApi::Provider::getProviders().empty()) { - ui::ToastError::open(fmt::format("{}{}", "hex.builtin.popup.error.project.load"_lang, "hex.builtin.popup.error.project.load.no_providers"_lang, warningMessage)); + // the warnings that happened when opening them + if (ImHexApi::Provider::getProviders().empty()) + { + ui::ToastError::open(fmt::format("{}{}", + "hex.builtin.popup.error.project.load"_lang, + "hex.builtin.popup.error.project.load.no_providers"_lang, + warningMessage)); return false; - } else { + } + else + { // Else, if there are warnings, still display them - if (warningMessage.empty()) { + if (warningMessage.empty()) + { return true; - } else { - ui::ToastWarning::open(fmt::format("hex.builtin.popup.error.project.load.some_providers_failed"_lang, warningMessage)); + } + else + { + ui::ToastWarning::open(fmt::format( + "hex.builtin.popup.error.project.load.some_providers_failed"_lang, + warningMessage)); } return success; } }, - .store = [](const std::fs::path &basePath, const Tar &tar) { + .store = + [](const std::fs::path& basePath, const Tar& tar) + { std::vector providerIds; - for (const auto &provider : ImHexApi::Provider::getProviders()) { + for (const auto& provider : ImHexApi::Provider::getProviders()) + { auto id = provider->getID(); providerIds.push_back(id); @@ -120,17 +165,18 @@ namespace hex::plugin::builtin { json["type"] = provider->getTypeName(); json["settings"] = provider->storeSettings({}); - tar.writeString(basePath / fmt::format("{}.json", id), json.dump(4)); + tar.writeString( + basePath / fmt::format("{}.json", id), json.dump(4)); } tar.writeString(basePath / "providers.json", - nlohmann::json({ { "providers", providerIds } }).dump(4) - ); + nlohmann::json({ + {"providers", providerIds} + }) + .dump(4)); return true; - } - }); + }}); } } - diff --git a/src/gui2/imhex_overrides/views.cpp b/src/gui2/imhex_overrides/views.cpp index 2ff13e92..79b6ec93 100644 --- a/src/gui2/imhex_overrides/views.cpp +++ b/src/gui2/imhex_overrides/views.cpp @@ -9,7 +9,6 @@ #include "content/views/view_patches.hpp" #include "content/views/view_command_palette.hpp" #include "content/views/view_settings.hpp" -#include "content/views/view_constants.hpp" #include "content/views/view_store.hpp" #include "content/views/view_provider_settings.hpp" #include "content/views/view_find.hpp" @@ -34,7 +33,6 @@ namespace hex::plugin::builtin { ContentRegistry::Views::add(); ContentRegistry::Views::add(); ContentRegistry::Views::add(); - ContentRegistry::Views::add(); ContentRegistry::Views::add(); ContentRegistry::Views::add(); ContentRegistry::Views::add(); @@ -62,4 +60,4 @@ namespace hex::plugin::builtin { }); } -} \ No newline at end of file +} diff --git a/src/gui2/logview.cc b/src/gui2/logview.cc index b7ff2c3e..682be925 100644 --- a/src/gui2/logview.cc +++ b/src/gui2/logview.cc @@ -66,3 +66,7 @@ void LogView::logMessage(const AnyLogMessage& message) logRenderer->add(message); scrollToEndOnNextRedraw = true; } + +void LogView::drawHelpText() +{ +} \ No newline at end of file diff --git a/src/gui2/logview.h b/src/gui2/logview.h index 25ca56b9..9a408a42 100644 --- a/src/gui2/logview.h +++ b/src/gui2/logview.h @@ -10,6 +10,7 @@ class LogView : public hex::View::Window ~LogView() override = default; void drawContent() override; + void drawHelpText() override; static void logMessage(const AnyLogMessage& message); [[nodiscard]] bool shouldDraw() const override diff --git a/src/gui2/summaryview.cc b/src/gui2/summaryview.cc index e832b5e5..0870f845 100644 --- a/src/gui2/summaryview.cc +++ b/src/gui2/summaryview.cc @@ -395,3 +395,7 @@ void SummaryView::drawContent() } } } + +void SummaryView::drawHelpText() +{ +} \ No newline at end of file diff --git a/src/gui2/summaryview.h b/src/gui2/summaryview.h index 42952e64..dd4af17b 100644 --- a/src/gui2/summaryview.h +++ b/src/gui2/summaryview.h @@ -9,6 +9,7 @@ class SummaryView : public hex::View::Window ~SummaryView() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { diff --git a/src/gui2/visualiserview.cc b/src/gui2/visualiserview.cc index 70e7a1ee..2ffcba26 100644 --- a/src/gui2/visualiserview.cc +++ b/src/gui2/visualiserview.cc @@ -174,3 +174,7 @@ void VisualiserView::drawContent() pos + ImVec2(size.x / 2, size.y - 100), size.x * 0.7); } + +void VisualiserView::drawHelpText() +{ +} diff --git a/src/gui2/visualiserview.h b/src/gui2/visualiserview.h index 803ee523..5b41a202 100644 --- a/src/gui2/visualiserview.h +++ b/src/gui2/visualiserview.h @@ -10,6 +10,7 @@ class VisualiserView : public hex::View::Window ~VisualiserView() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { From 8d811f6452ffa8f80fb7f06ca8d7f6f50dd1b3b2 Mon Sep 17 00:00:00 2001 From: Stephen Pick <3457029+the-claw@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:36:36 +0100 Subject: [PATCH 2/4] Undo auto-reformatting of main_menu_items.cpp --- dep/build.py | 1 + src/gui2/imhex_overrides/main_menu_items.cpp | 1356 ++++++------------ 2 files changed, 440 insertions(+), 917 deletions(-) diff --git a/dep/build.py b/dep/build.py index 002c5fb9..bb950c75 100644 --- a/dep/build.py +++ b/dep/build.py @@ -903,6 +903,7 @@ name="patternlanguage_repo", url="https://github.com/WerWolv/PatternLanguage", branch="master", + commit="2e49805fcc715acdc8706f87467a8d0ed7268855", path="dep/r/pattern-language", ), ], diff --git a/src/gui2/imhex_overrides/main_menu_items.cpp b/src/gui2/imhex_overrides/main_menu_items.cpp index 80dd3b59..fa672e68 100644 --- a/src/gui2/imhex_overrides/main_menu_items.cpp +++ b/src/gui2/imhex_overrides/main_menu_items.cpp @@ -26,6 +26,7 @@ #include #include + #include #include @@ -38,1094 +39,615 @@ using namespace std::literals::string_literals; using namespace wolv::literals; -namespace hex::plugin::builtin -{ +namespace hex::plugin::builtin { - namespace - { + namespace { - bool noRunningTasks() - { return TaskManager::getRunningTaskCount() == 0; } + bool noRunningTasks() { + return TaskManager::getRunningTaskCount() == 0; + } - bool noRunningTaskAndValidProvider() - { return noRunningTasks() && ImHexApi::Provider::isValid(); } + bool noRunningTaskAndValidProvider() { + return noRunningTasks() && ImHexApi::Provider::isValid(); + } - bool noRunningTaskAndWritableProvider() - { - return noRunningTasks() && ImHexApi::Provider::isValid() && - ImHexApi::Provider::get()->isWritable(); + bool noRunningTaskAndWritableProvider() { + return noRunningTasks() && ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isWritable(); } } - namespace - { - - void handleIPSError(IPSError error) - { - TaskManager::doLater( - [error] - { - switch (error) - { - case IPSError::InvalidPatchHeader: - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); - break; - case IPSError::AddressOutOfRange: - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); - break; - case IPSError::PatchTooLarge: - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); - break; - case IPSError::InvalidPatchFormat: - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); - break; - case IPSError::MissingEOF: - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); - break; - } - }); + namespace { + + void handleIPSError(IPSError error) { + TaskManager::doLater([error]{ + switch (error) { + case IPSError::InvalidPatchHeader: + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_header_error"_lang); + break; + case IPSError::AddressOutOfRange: + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.address_out_of_range_error"_lang); + break; + case IPSError::PatchTooLarge: + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.patch_too_large_error"_lang); + break; + case IPSError::InvalidPatchFormat: + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.invalid_patch_format_error"_lang); + break; + case IPSError::MissingEOF: + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.missing_eof_error"_lang); + break; + } + }); } } // Import - namespace - { - - void importIPSPatch() - { - fs::openFileBrowser(fs::DialogMode::Open, - {}, - [](const auto& path) - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [path](auto& task) - { - auto patchData = - wolv::io::File(path, wolv::io::File::Mode::Read) - .readVector(); - auto patch = Patches::fromIPSPatch(patchData); - if (!patch.has_value()) - { - handleIPSError(patch.error()); - return; - } + namespace { + + void importIPSPatch() { + fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { + auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); + auto patch = Patches::fromIPSPatch(patchData); + if (!patch.has_value()) { + handleIPSError(patch.error()); + return; + } - task.setMaxValue(patch->get().size()); + task.setMaxValue(patch->get().size()); - auto provider = ImHexApi::Provider::get(); + auto provider = ImHexApi::Provider::get(); - for (auto& [address, value] : patch->get()) - { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + for (auto &[address, value] : patch->get()) { + provider->write(address, &value, sizeof(value)); + task.increment(); + } - provider->getUndoStack().groupOperations( - patch->get().size(), - "hex.builtin.undo_operation.patches"); - }); + provider->getUndoStack().groupOperations(patch->get().size(), "hex.builtin.undo_operation.patches"); }); + }); } - void importIPS32Patch() - { - fs::openFileBrowser(fs::DialogMode::Open, - {}, - [](const auto& path) - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [path](auto& task) - { - auto patchData = - wolv::io::File(path, wolv::io::File::Mode::Read) - .readVector(); - auto patch = Patches::fromIPS32Patch(patchData); - if (!patch.has_value()) - { - handleIPSError(patch.error()); - return; - } + void importIPS32Patch() { + fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { + auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); + auto patch = Patches::fromIPS32Patch(patchData); + if (!patch.has_value()) { + handleIPSError(patch.error()); + return; + } - task.setMaxValue(patch->get().size()); + task.setMaxValue(patch->get().size()); - auto provider = ImHexApi::Provider::get(); + auto provider = ImHexApi::Provider::get(); - for (auto& [address, value] : patch->get()) - { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + for (auto &[address, value] : patch->get()) { + provider->write(address, &value, sizeof(value)); + task.increment(); + } - provider->getUndoStack().groupOperations( - patch->get().size(), - "hex.builtin.undo_operation.patches"); - }); + provider->getUndoStack().groupOperations(patch->get().size(), "hex.builtin.undo_operation.patches"); }); + }); } - void importModifiedFile() - { - fs::openFileBrowser(fs::DialogMode::Open, - {}, - [](const auto& path) - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [path](auto& task) - { - auto provider = ImHexApi::Provider::get(); - auto patchData = - wolv::io::File(path, wolv::io::File::Mode::Read) - .readVector(); - - if (patchData.size() != provider->getActualSize()) - { - ui::ToastError::open( - "hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); - return; - } + void importModifiedFile() { + fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { + auto provider = ImHexApi::Provider::get(); + auto patchData = wolv::io::File(path, wolv::io::File::Mode::Read).readVector(); - const auto baseAddress = provider->getBaseAddress(); + if (patchData.size() != provider->getActualSize()) { + ui::ToastError::open("hex.builtin.menu.file.import.modified_file.popup.invalid_size"_lang); + return; + } - std::map patches; - for (u64 i = 0; i < patchData.size(); i++) - { - u8 value = 0; - provider->read(baseAddress + i, &value, 1); + const auto baseAddress = provider->getBaseAddress(); - if (value != patchData[i]) - patches[baseAddress + i] = patchData[i]; - } + std::map patches; + for (u64 i = 0; i < patchData.size(); i++) { + u8 value = 0; + provider->read(baseAddress + i, &value, 1); - task.setMaxValue(patches.size()); + if (value != patchData[i]) + patches[baseAddress + i] = patchData[i]; + } - for (auto& [address, value] : patches) - { - provider->write(address, &value, sizeof(value)); - task.increment(); - } + task.setMaxValue(patches.size()); - provider->getUndoStack().groupOperations( - patches.size(), - "hex.builtin.undo_operation.patches"); - }); + for (auto &[address, value] : patches) { + provider->write(address, &value, sizeof(value)); + task.increment(); + } + + provider->getUndoStack().groupOperations(patches.size(), "hex.builtin.undo_operation.patches"); }); + }); } } // Export - namespace - { + namespace { + + void exportBase64() { + fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &) { + wolv::io::File outputFile(path, wolv::io::File::Mode::Create); + if (!outputFile.isValid()) { + TaskManager::doLater([] { + ui::ToastError::open("hex.builtin.menu.file.export.error.create_file"_lang); + }); + return; + } - void exportBase64() - { - fs::openFileBrowser(fs::DialogMode::Save, - {}, - [](const auto& path) - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [path](auto&) - { - wolv::io::File outputFile( - path, wolv::io::File::Mode::Create); - if (!outputFile.isValid()) - { - TaskManager::doLater( - [] - { - ui::ToastError::open( - "hex.builtin.menu.file.export.error.create_file"_lang); - }); - return; - } + auto provider = ImHexApi::Provider::get(); + std::vector bytes(5_MiB); + for (u64 address = 0; address < provider->getActualSize(); address += bytes.size()) { + bytes.resize(std::min(bytes.size(), provider->getActualSize() - address)); + provider->read(provider->getBaseAddress() + address, bytes.data(), bytes.size()); - auto provider = ImHexApi::Provider::get(); - std::vector bytes(5_MiB); - for (u64 address = 0; - address < provider->getActualSize(); - address += bytes.size()) - { - bytes.resize(std::min(bytes.size(), - provider->getActualSize() - address)); - provider->read( - provider->getBaseAddress() + address, - bytes.data(), - bytes.size()); - - outputFile.writeVector(crypt::encode64(bytes)); - } - }); + outputFile.writeVector(crypt::encode64(bytes)); + } }); + }); } - void exportSelectionToFile() - { - fs::openFileBrowser(fs::DialogMode::Save, - {}, - [](const auto& path) - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [path](auto& task) - { - wolv::io::File outputFile( - path, wolv::io::File::Mode::Create); - if (!outputFile.isValid()) - { - TaskManager::doLater( - [] - { - ui::ToastError::open( - "hex.builtin.menu.file.export.error.create_file"_lang); - }); - return; - } - - auto provider = ImHexApi::Provider::get(); - std::vector bytes(5_MiB); - - auto selection = - ImHexApi::HexEditor::getSelection(); - for (u64 address = selection->getStartAddress(); - address <= selection->getEndAddress(); - address += bytes.size()) - { - bytes.resize(std::min(bytes.size(), - selection->getEndAddress() - address + 1)); - provider->read( - address, bytes.data(), bytes.size()); - - outputFile.writeVector(bytes); - task.update(); - } + void exportSelectionToFile() { + fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) { + wolv::io::File outputFile(path, wolv::io::File::Mode::Create); + if (!outputFile.isValid()) { + TaskManager::doLater([] { + ui::ToastError::open("hex.builtin.menu.file.export.error.create_file"_lang); }); + return; + } + + auto provider = ImHexApi::Provider::get(); + std::vector bytes(5_MiB); + + auto selection = ImHexApi::HexEditor::getSelection(); + for (u64 address = selection->getStartAddress(); address <= selection->getEndAddress(); address += bytes.size()) { + bytes.resize(std::min(bytes.size(), selection->getEndAddress() - address + 1)); + provider->read(address, bytes.data(), bytes.size()); + + outputFile.writeVector(bytes); + task.update(); + } }); + }); } - void drawExportLanguageMenu() - { - for (const auto& formatter : - ContentRegistry::DataFormatter::impl::getExportMenuEntries()) - { - if (menu::menuItem(Lang(formatter.unlocalizedName), - Shortcut::None, - false, - ImHexApi::Provider::isValid() && - ImHexApi::Provider::get()->getActualSize() > 0)) - { - fs::openFileBrowser(fs::DialogMode::Save, - {}, - [&formatter](const auto& path) - { - TaskManager::createTask( - "hex.builtin.task.exporting_data", - TaskManager::NoProgress, - [&formatter, path](auto&) - { - auto provider = ImHexApi::Provider::get(); - auto selection = - ImHexApi::HexEditor::getSelection() - .value_or(ImHexApi::HexEditor:: - ProviderRegion{ - {provider - ->getBaseAddress(), - provider - ->getSize()}, - provider - }); - - auto result = formatter.callback(provider, - selection.getStartAddress(), - selection.getSize(), - false); - - wolv::io::File file( - path, wolv::io::File::Mode::Create); - if (!file.isValid()) - { - TaskManager::doLater( - [] - { - ui::ToastError::open( - "hex.builtin.menu.file.export.as_language.popup.export_error"_lang); - }); - return; - } - - file.writeString(result); + void drawExportLanguageMenu() { + for (const auto &formatter : ContentRegistry::DataFormatter::impl::getExportMenuEntries()) { + if (menu::menuItem(Lang(formatter.unlocalizedName), Shortcut::None, false, ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->getActualSize() > 0)) { + fs::openFileBrowser(fs::DialogMode::Save, {}, [&formatter](const auto &path) { + TaskManager::createTask("hex.builtin.task.exporting_data", TaskManager::NoProgress, [&formatter, path](auto&){ + auto provider = ImHexApi::Provider::get(); + auto selection = ImHexApi::HexEditor::getSelection() + .value_or( + ImHexApi::HexEditor::ProviderRegion { + { provider->getBaseAddress(), provider->getSize() }, + provider }); + + auto result = formatter.callback(provider, selection.getStartAddress(), selection.getSize(), false); + + wolv::io::File file(path, wolv::io::File::Mode::Create); + if (!file.isValid()) { + TaskManager::doLater([] { + ui::ToastError::open("hex.builtin.menu.file.export.as_language.popup.export_error"_lang); + }); + return; + } + + file.writeString(result); }); + }); } } } - void exportReport() - { - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [](auto&) - { - std::string data; - - for (const auto& provider : - ImHexApi::Provider::getProviders()) - { - data += fmt::format("# {}", provider->getName()); - data += "\n\n"; + void exportReport() { + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [](auto &) { + std::string data; - for (const auto& generator : - ContentRegistry::Reports::impl::getGenerators()) - { - data += generator.callback(provider); - data += "\n\n"; - } + for (const auto &provider : ImHexApi::Provider::getProviders()) { + data += fmt::format("# {}", provider->getName()); + data += "\n\n"; + + for (const auto &generator : ContentRegistry::Reports::impl::getGenerators()) { + data += generator.callback(provider); data += "\n\n"; } + data += "\n\n"; + } - TaskManager::doLater( - [data] - { - fs::openFileBrowser(fs::DialogMode::Save, - { - {"Markdown File", "md"} - }, - [&data](const auto& path) - { - auto file = wolv::io::File( - path, wolv::io::File::Mode::Create); - if (!file.isValid()) - { - ui::ToastError::open( - "hex.builtin.menu.file.export.report.popup.export_error"_lang); - return; - } - - file.writeString(data); - }); - }); + TaskManager::doLater([data] { + fs::openFileBrowser(fs::DialogMode::Save, { { "Markdown File", "md" }}, [&data](const auto &path) { + auto file = wolv::io::File(path, wolv::io::File::Mode::Create); + if (!file.isValid()) { + ui::ToastError::open("hex.builtin.menu.file.export.report.popup.export_error"_lang); + return; + } + + file.writeString(data); + }); }); + }); } - void exportIPSPatch() - { + void exportIPSPatch() { auto provider = ImHexApi::Provider::get(); auto patches = Patches::fromProvider(provider); - if (!patches.has_value()) - { + if (!patches.has_value()) { handleIPSError(patches.error()); return; } - // Make sure there's no patch at address 0x00454F46 because that - // would cause the patch to contain the sequence "EOF" which signals - // the end of the patch - if (!patches->get().contains(0x00454F45) && - patches->get().contains(0x00454F46)) - { + // Make sure there's no patch at address 0x00454F46 because that would cause the patch to contain the sequence "EOF" which signals the end of the patch + if (!patches->get().contains(0x00454F45) && patches->get().contains(0x00454F46)) { u8 value = 0; provider->read(0x00454F45, &value, sizeof(u8)); patches->get().at(0x00454F45) = value; } - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [patches](auto&) - { - auto data = patches->toIPSPatch(); - - TaskManager::doLater( - [data] - { - fs::openFileBrowser(fs::DialogMode::Save, - {}, - [&data](const auto& path) - { - auto file = wolv::io::File( - path, wolv::io::File::Mode::Create); - if (!file.isValid()) - { - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.export_error"_lang); - return; - } - - if (data.has_value()) - { - const auto& bytes = data.value(); - file.writeVector(bytes); - EventPatchCreated::post(bytes.data(), - bytes.size(), - PatchKind::IPS); - } - else - { - handleIPSError(data.error()); - } - }); - }); + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [patches](auto &) { + auto data = patches->toIPSPatch(); + + TaskManager::doLater([data] { + fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { + auto file = wolv::io::File(path, wolv::io::File::Mode::Create); + if (!file.isValid()) { + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); + return; + } + + if (data.has_value()) { + const auto& bytes = data.value(); + file.writeVector(bytes); + EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS); + } else { + handleIPSError(data.error()); + } + }); }); + }); } - void exportIPS32Patch() - { + void exportIPS32Patch() { auto provider = ImHexApi::Provider::get(); auto patches = Patches::fromProvider(provider); - if (!patches.has_value()) - { + if (!patches.has_value()) { handleIPSError(patches.error()); return; } - // Make sure there's no patch at address 0x45454F46 because that - // would cause the patch to contain the sequence "*EOF" which - // signals the end of the patch - if (!patches->get().contains(0x45454F45) && - patches->get().contains(0x45454F46)) - { + // Make sure there's no patch at address 0x45454F46 because that would cause the patch to contain the sequence "*EOF" which signals the end of the patch + if (!patches->get().contains(0x45454F45) && patches->get().contains(0x45454F46)) { u8 value = 0; provider->read(0x45454F45, &value, sizeof(u8)); patches->get().at(0x45454F45) = value; } - TaskManager::createTask("hex.ui.common.processing", - TaskManager::NoProgress, - [patches](auto&) - { - auto data = patches->toIPS32Patch(); - - TaskManager::doLater( - [data] - { - fs::openFileBrowser(fs::DialogMode::Save, - {}, - [&data](const auto& path) - { - auto file = wolv::io::File( - path, wolv::io::File::Mode::Create); - if (!file.isValid()) - { - ui::ToastError::open( - "hex.builtin.menu.file.export.ips.popup.export_error"_lang); - return; - } - - if (data.has_value()) - { - const std::vector& bytes = - data.value(); - file.writeVector(bytes); - EventPatchCreated::post(bytes.data(), - bytes.size(), - PatchKind::IPS32); - } - else - { - handleIPSError(data.error()); - } - }); - }); + TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [patches](auto &) { + auto data = patches->toIPS32Patch(); + + TaskManager::doLater([data] { + fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { + auto file = wolv::io::File(path, wolv::io::File::Mode::Create); + if (!file.isValid()) { + ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); + return; + } + + if (data.has_value()) { + const std::vector& bytes = data.value(); + file.writeVector(bytes); + EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS32); + } else { + handleIPSError(data.error()); + } + }); }); + }); } } + /** - * @brief returns true if there is a currently selected provider, and it is - * possibl to dump data from it + * @brief returns true if there is a currently selected provider, and it is possibl to dump data from it */ - bool isProviderDumpable() - { + bool isProviderDumpable() { auto provider = ImHexApi::Provider::get(); return ImHexApi::Provider::isValid() && provider->isDumpable(); } - static void createFileMenu() - { + static void createFileMenu() { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.file", 1000); + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.file", 1000); /* Create File */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", "hex.builtin.menu.file.create_file"}, - ICON_VS_FILE, - 1050, - CTRLCMD + Keys::N + AllowWhileTyping, - [] - { - auto newProvider = hex::ImHexApi::Provider::createProvider( - "hex.builtin.provider.mem_file", true); - if (newProvider != nullptr && newProvider->open().isFailure()) - hex::ImHexApi::Provider::remove(newProvider.get()); - else - EventProviderOpened::post(newProvider.get()); - }, - noRunningTasks); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.create_file" }, ICON_VS_FILE, 1050, CTRLCMD + Keys::N + AllowWhileTyping, [] { + auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true); + if (newProvider != nullptr && newProvider->open().isFailure()) + hex::ImHexApi::Provider::remove(newProvider.get()); + else + EventProviderOpened::post(newProvider.get()); + }, noRunningTasks); /* Open File */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", "hex.builtin.menu.file.open_file"}, - ICON_VS_FOLDER_OPENED, - 1100, - CTRLCMD + Keys::O + AllowWhileTyping + ShowOnWelcomeScreen, - [] - { - RequestOpenWindow::post("Open File"); - }, - noRunningTasks, - ContentRegistry::Views::getViewByName( - "hex.builtin.view.hex_editor.name")); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.open_file" }, ICON_VS_FOLDER_OPENED, 1100, CTRLCMD + Keys::O + AllowWhileTyping + ShowOnWelcomeScreen, [] { + RequestOpenWindow::post("Open File"); + }, noRunningTasks, ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name")); /* Open Other */ - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.file", "hex.builtin.menu.file.open_other"}, - ICON_VS_TELESCOPE, - 1150, - [] - { - for (const auto& [unlocalizedProviderName, icon] : - ContentRegistry::Provider::impl::getEntries()) - { - if (menu::menuItemEx(Lang(unlocalizedProviderName), icon)) - ImHexApi::Provider::createProvider( - unlocalizedProviderName); - } - }, - noRunningTasks); + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.open_other"}, ICON_VS_TELESCOPE, 1150, [] { + for (const auto &[unlocalizedProviderName, icon] : ContentRegistry::Provider::impl::getEntries()) { + if (menu::menuItemEx(Lang(unlocalizedProviderName), icon)) + ImHexApi::Provider::createProvider(unlocalizedProviderName); + } + }, noRunningTasks); /* Reload Provider */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", "hex.builtin.menu.file.reload_provider"}, - ICON_VS_REFRESH, - 1250, - CTRLCMD + Keys::R + AllowWhileTyping, - [] - { - auto provider = ImHexApi::Provider::get(); - - provider->close(); - if (provider->open().isFailure()) - ImHexApi::Provider::remove(provider, true); - - EventDataChanged::post(provider); - }, - noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.reload_provider"}, ICON_VS_REFRESH, 1250, CTRLCMD + Keys::R + AllowWhileTyping, [] { + auto provider = ImHexApi::Provider::get(); + + provider->close(); + if (provider->open().isFailure()) + ImHexApi::Provider::remove(provider, true); + + EventDataChanged::post(provider); + }, noRunningTaskAndValidProvider); + /* Project open / save */ - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.file", "hex.builtin.menu.file.project"}, - ICON_VS_NOTEBOOK, - 1400, - [] - { - }, - noRunningTasks); - - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.project", - "hex.builtin.menu.file.project.open"}, - ICON_VS_ROOT_FOLDER_OPENED, - 1410, - CTRL + ALT + Keys::O + AllowWhileTyping, - openProject, - noRunningTasks); - - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.project", - "hex.builtin.menu.file.project.save"}, - ICON_VS_SAVE, - 1450, - CTRL + ALT + Keys::S + AllowWhileTyping, - saveProject, - [&] - { - return noRunningTaskAndValidProvider() && - ProjectFile::hasPath(); - }); + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.project" }, ICON_VS_NOTEBOOK, 1400, []{}, noRunningTasks); + + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.open" }, ICON_VS_ROOT_FOLDER_OPENED, 1410, + CTRL + ALT + Keys::O + AllowWhileTyping, + openProject, noRunningTasks); + + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save" }, ICON_VS_SAVE, 1450, + CTRL + ALT + Keys::S + AllowWhileTyping, + saveProject, [&] { return noRunningTaskAndValidProvider() && ProjectFile::hasPath(); }); - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.project", - "hex.builtin.menu.file.project.save_as"}, - ICON_VS_SAVE_AS, - 1500, - ALT + SHIFT + Keys::S + AllowWhileTyping, - saveProjectAs, - noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save_as" }, ICON_VS_SAVE_AS, 1500, + ALT + SHIFT + Keys::S + AllowWhileTyping, + saveProjectAs, noRunningTaskAndValidProvider); - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.file"}, 2000); + + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 2000); /* Import */ { - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.file", "hex.builtin.menu.file.import"}, - ICON_VS_SIGN_IN, - 5140, - [] - { - }, - noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.import" }, ICON_VS_SIGN_IN, 5140, []{}, noRunningTaskAndValidProvider); /* IPS */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.import", - "hex.builtin.menu.file.import.ips"}, - ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, - 5150, - Shortcut::None, - importIPSPatch, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5150, + Shortcut::None, + importIPSPatch, + noRunningTaskAndWritableProvider); /* IPS32 */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.import", - "hex.builtin.menu.file.import.ips32"}, - ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, - 5200, - Shortcut::None, - importIPS32Patch, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips32"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5200, + Shortcut::None, + importIPS32Patch, + noRunningTaskAndWritableProvider); /* Modified File */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.import", - "hex.builtin.menu.file.import.modified_file"}, - ICON_VS_FILES, - 5300, - Shortcut::None, - importModifiedFile, - noRunningTaskAndWritableProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.modified_file" }, ICON_VS_FILES, 5300, + Shortcut::None, + importModifiedFile, + noRunningTaskAndWritableProvider); } /* Export */ /* Only make them accessible if the current provider is dumpable */ { - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.file", "hex.builtin.menu.file.export"}, - ICON_VS_SIGN_OUT, - 6000, - [] - { - }, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, ICON_VS_SIGN_OUT, 6000, []{}, isProviderDumpable); /* Selection to File */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.selection_to_file"}, - ICON_VS_FILE_BINARY, - 6010, - Shortcut::None, - exportSelectionToFile, - ImHexApi::HexEditor::isSelectionValid); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.selection_to_file" }, ICON_VS_FILE_BINARY, 6010, + Shortcut::None, + exportSelectionToFile, + ImHexApi::HexEditor::isSelectionValid); /* Base 64 */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.base64"}, - ICON_VS_NOTE, - 6020, - Shortcut::None, - exportBase64, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.base64" }, ICON_VS_NOTE, 6020, + Shortcut::None, + exportBase64, + isProviderDumpable); /* Language */ - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.as_language"}, - ICON_VS_CODE, - 6030, - drawExportLanguageMenu, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.as_language" }, ICON_VS_CODE, 6030, + drawExportLanguageMenu, + isProviderDumpable); /* Report */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.report"}, - ICON_VS_MARKDOWN, - 6040, - Shortcut::None, - exportReport, - ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.file", "hex.builtin.menu.file.export"}, - 6050); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.report" }, ICON_VS_MARKDOWN, 6040, + Shortcut::None, + exportReport, + ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, 6050); /* IPS */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.ips"}, - ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, - 6100, - Shortcut::None, - exportIPSPatch, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6100, + Shortcut::None, + exportIPSPatch, + isProviderDumpable); /* IPS32 */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", - "hex.builtin.menu.file.export", - "hex.builtin.menu.file.export.ips32"}, - ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, - 6150, - Shortcut::None, - exportIPS32Patch, - isProviderDumpable); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips32" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6150, + Shortcut::None, + exportIPS32Patch, + isProviderDumpable); } - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.file"}, 10000); + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 10000); /* Close Provider */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", "hex.builtin.menu.file.close"}, - ICON_VS_CHROME_CLOSE, - 10050, - CTRLCMD + Keys::W + AllowWhileTyping, - [] - { - ImHexApi::Provider::remove(ImHexApi::Provider::get()); - }, - noRunningTaskAndValidProvider); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.close"}, ICON_VS_CHROME_CLOSE, 10050, CTRLCMD + Keys::W + AllowWhileTyping, [] { + ImHexApi::Provider::remove(ImHexApi::Provider::get()); + }, noRunningTaskAndValidProvider); /* Quit ImHex */ - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.file", "hex.builtin.menu.file.quit"}, - ICON_VS_CLOSE_ALL, - 10100, - ALT + Keys::F4 + AllowWhileTyping, - [] - { - ImHexApi::System::closeImHex(); - }); + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.quit"}, ICON_VS_CLOSE_ALL, 10100, ALT + Keys::F4 + AllowWhileTyping, [] { + ImHexApi::System::closeImHex(); + }); } - static void createEditMenu() - { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.edit", 2000); + static void createEditMenu() { + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.edit", 2000); } - static void createViewMenu() - { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.view", 3000); - -#if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top"}, - ICON_VS_PINNED, - 1000, - Keys::F10 + AllowWhileTyping, - [] - { - static bool state = false; - - state = !state; - glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), - GLFW_FLOATING, - state); - }, - [] - { - return true; - }, - [] - { - return glfwGetWindowAttrib( - ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); - }); -#endif - -#if !defined(OS_MACOS) && !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen"}, - ICON_VS_SCREEN_FULL, - 2000, - Keys::F11 + AllowWhileTyping, - [] - { - static bool state = false; - static ImVec2 position, size; - - state = !state; - - const auto window = ImHexApi::System::getMainWindowHandle(); - if (state) - { - position = ImHexApi::System::getMainWindowPosition(); - size = ImHexApi::System::getMainWindowSize(); - - const auto monitor = glfwGetPrimaryMonitor(); - const auto videoMode = glfwGetVideoMode(monitor); - - glfwSetWindowMonitor(window, - monitor, - 0, - 0, - videoMode->width, - videoMode->height, - videoMode->refreshRate); - } - else - { - glfwSetWindowMonitor(window, - nullptr, - position.x, - position.y, - size.x, - size.y, - 0); - glfwSetWindowAttrib(window, - GLFW_DECORATED, - ImHexApi::System::isBorderlessWindowModeEnabled() - ? GLFW_FALSE - : GLFW_TRUE); - } - }, - [] - { - return true; - }, - [] - { - return glfwGetWindowMonitor( - ImHexApi::System::getMainWindowHandle()) != nullptr; - }); -#endif - -#if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.view"}, 3000); -#endif - - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.view"}, - 4000, - [] - { - for (auto& [name, view] : - ContentRegistry::Views::impl::getEntries()) - { - if (view->hasViewMenuItemEntry()) - { - auto& state = view->getWindowOpenState(); - - if (menu::menuItemEx(Lang(view->getUnlocalizedName()), - view->getIcon(), - Shortcut::None, - state, - ImHexApi::Provider::isValid() && - !LayoutManager::isLayoutLocked())) - state = !state; - } + static void createViewMenu() { + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.view", 3000); + + #if !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top" }, ICON_VS_PINNED, 1000, Keys::F10 + AllowWhileTyping, [] { + static bool state = false; + + state = !state; + glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING, state); + }, []{ return true; }, []{ return glfwGetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); }); + #endif + + #if !defined(OS_MACOS) && !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen" }, ICON_VS_SCREEN_FULL, 2000, Keys::F11 + AllowWhileTyping, [] { + static bool state = false; + static ImVec2 position, size; + + state = !state; + + + const auto window = ImHexApi::System::getMainWindowHandle(); + if (state) { + position = ImHexApi::System::getMainWindowPosition(); + size = ImHexApi::System::getMainWindowSize(); + + const auto monitor = glfwGetPrimaryMonitor(); + const auto videoMode = glfwGetVideoMode(monitor); + + glfwSetWindowMonitor(window, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); + } else { + glfwSetWindowMonitor(window, nullptr, position.x, position.y, size.x, size.y, 0); + glfwSetWindowAttrib(window, GLFW_DECORATED, ImHexApi::System::isBorderlessWindowModeEnabled() ? GLFW_FALSE : GLFW_TRUE); + } + + }, []{ return true; }, []{ return glfwGetWindowMonitor(ImHexApi::System::getMainWindowHandle()) != nullptr; }); + #endif + + #if !defined(OS_WEB) + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.view" }, 3000); + #endif + + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.view" }, 4000, [] { + for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) { + if (view->hasViewMenuItemEntry()) { + auto &state = view->getWindowOpenState(); + + if (menu::menuItemEx(Lang(view->getUnlocalizedName()), view->getIcon(), Shortcut::None, state, ImHexApi::Provider::isValid() && !LayoutManager::isLayoutLocked())) + state = !state; } - }); + } + }); + } - static void createLayoutMenu() - { + static void createLayoutMenu() { LayoutManager::reload(); - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, - ICON_VS_LAYOUT, - 1050, - [] - { - }, - ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.workspace", - "hex.builtin.menu.workspace.layout", - "hex.builtin.menu.workspace.layout.save"}, - 1100, - Shortcut::None, - [] - { - ui::PopupTextInput::open("hex.builtin.popup.save_layout.title", - "hex.builtin.popup.save_layout.desc", - [](const std::string& name) - { - LayoutManager::save(name); - }); - }, - ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, - ICON_VS_LAYOUT, - 1150, - [] - { - bool locked = LayoutManager::isLayoutLocked(); - if (menu::menuItemEx( - "hex.builtin.menu.workspace.layout.lock"_lang, - ICON_VS_LOCK, - Shortcut::None, - locked, - ImHexApi::Provider::isValid())) - { - LayoutManager::lockLayout(!locked); - ContentRegistry::Settings::write( - "hex.builtin.setting.interface", - "hex.builtin.setting.interface.layout_locked", - !locked); - } + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, ICON_VS_LAYOUT, 1050, []{}, ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout", "hex.builtin.menu.workspace.layout.save" }, 1100, Shortcut::None, [] { + ui::PopupTextInput::open("hex.builtin.popup.save_layout.title", "hex.builtin.popup.save_layout.desc", [](const std::string &name) { + LayoutManager::save(name); }); + }, ImHexApi::Provider::isValid); - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, - 1200); - - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout"}, - 2000, - [] - { - for (const auto& path : romfs::list("layouts")) - { - if (menu::menuItem( - wolv::util::capitalizeString(path.stem().string()) - .c_str(), - Shortcut::None, - false, - ImHexApi::Provider::isValid())) - { - LayoutManager::loadFromString( - std::string(romfs::get(path).string())); - } + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, ICON_VS_LAYOUT, 1150, [] { + bool locked = LayoutManager::isLayoutLocked(); + if (menu::menuItemEx("hex.builtin.menu.workspace.layout.lock"_lang, ICON_VS_LOCK, Shortcut::None, locked, ImHexApi::Provider::isValid())) { + LayoutManager::lockLayout(!locked); + ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.layout_locked", !locked); + } + }); + + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 1200); + + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 2000, [] { + for (const auto &path : romfs::list("layouts")) { + if (menu::menuItem(wolv::util::capitalizeString(path.stem().string()).c_str(), Shortcut::None, false, ImHexApi::Provider::isValid())) { + LayoutManager::loadFromString(std::string(romfs::get(path).string())); } + } - bool shiftPressed = ImGui::GetIO().KeyShift; - for (auto& [name, path] : LayoutManager::getLayouts()) - { - if (menu::menuItem( - fmt::format("{}{}", - name, - shiftPressed ? " " ICON_VS_CHROME_CLOSE : "") - .c_str(), - Shortcut::None, - false, - ImHexApi::Provider::isValid())) - { - if (shiftPressed) - { - LayoutManager::removeLayout(name); - break; - } - else - { - LayoutManager::load(path); - } + bool shiftPressed = ImGui::GetIO().KeyShift; + for (auto &[name, path] : LayoutManager::getLayouts()) { + if (menu::menuItem(fmt::format("{}{}", name, shiftPressed ? " " ICON_VS_CHROME_CLOSE : "").c_str(), Shortcut::None, false, ImHexApi::Provider::isValid())) { + if (shiftPressed) { + LayoutManager::removeLayout(name); + break; + } else { + LayoutManager::load(path); } } - }); + } + }); } - static void createWorkspaceMenu() - { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.workspace", 4000); + static void createWorkspaceMenu() { + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.workspace", 4000); createLayoutMenu(); - ContentRegistry::UserInterface::addMenuItemSeparator( - {"hex.builtin.menu.workspace"}, 3000); - - ContentRegistry::UserInterface::addMenuItem( - {"hex.builtin.menu.workspace", "hex.builtin.menu.workspace.create"}, - ICON_VS_ADD, - 3100, - Shortcut::None, - [] - { - ui::PopupTextInput::open( - "hex.builtin.popup.create_workspace.title", - "hex.builtin.popup.create_workspace.desc", - [](const std::string& name) - { - WorkspaceManager::createWorkspace(name); - }); - }, - ImHexApi::Provider::isValid); - - ContentRegistry::UserInterface::addMenuItemSubMenu( - {"hex.builtin.menu.workspace"}, - 3200, - [] - { - const auto& workspaces = WorkspaceManager::getWorkspaces(); - - bool shiftPressed = ImGui::GetIO().KeyShift; - for (auto it = workspaces.begin(); it != workspaces.end(); ++it) - { - const auto& [name, workspace] = *it; - - bool canRemove = shiftPressed && !workspace.builtin; - if (menu::menuItem( - fmt::format("{}{}", - name, - canRemove ? " " ICON_VS_CHROME_CLOSE : "") - .c_str(), - Shortcut::None, - it == WorkspaceManager::getCurrentWorkspace(), - ImHexApi::Provider::isValid())) - { - if (canRemove) - { - WorkspaceManager::removeWorkspace(name); - break; - } - else - { - WorkspaceManager::switchWorkspace(name); - } + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.workspace" }, 3000); + + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.create" }, ICON_VS_ADD, 3100, Shortcut::None, [] { + ui::PopupTextInput::open("hex.builtin.popup.create_workspace.title", "hex.builtin.popup.create_workspace.desc", [](const std::string &name) { + WorkspaceManager::createWorkspace(name); + }); + }, ImHexApi::Provider::isValid); + + ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.workspace" }, 3200, [] { + const auto &workspaces = WorkspaceManager::getWorkspaces(); + + bool shiftPressed = ImGui::GetIO().KeyShift; + for (auto it = workspaces.begin(); it != workspaces.end(); ++it) { + const auto &[name, workspace] = *it; + + bool canRemove = shiftPressed && !workspace.builtin; + if (menu::menuItem(fmt::format("{}{}", name, canRemove ? " " ICON_VS_CHROME_CLOSE : "").c_str(), Shortcut::None, it == WorkspaceManager::getCurrentWorkspace(), ImHexApi::Provider::isValid())) { + if (canRemove) { + WorkspaceManager::removeWorkspace(name); + break; + } else { + WorkspaceManager::switchWorkspace(name); } } - }); + } + }); } - static void createExtrasMenu() - { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.extras", 5000); + static void createExtrasMenu() { + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.extras", 5000); } - static void createHelpMenu() - { - ContentRegistry::UserInterface::registerMainMenuItem( - "hex.builtin.menu.help", 6000); + static void createHelpMenu() { + ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.help", 6000); } - void registerMainMenuEntries() - { + + void registerMainMenuEntries() { createFileMenu(); createEditMenu(); createViewMenu(); @@ -1134,4 +656,4 @@ namespace hex::plugin::builtin createHelpMenu(); } -} \ No newline at end of file +} From b2e3e4cfed6ab42e4acf0d20142033a30d6220a5 Mon Sep 17 00:00:00 2001 From: Stephen Pick <3457029+the-claw@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:43:21 +0100 Subject: [PATCH 3/4] Undo auto-indenting of main_menu_items.cpp --- src/gui2/imhex_overrides/main_menu_items.cpp | 118 +++++++++---------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/gui2/imhex_overrides/main_menu_items.cpp b/src/gui2/imhex_overrides/main_menu_items.cpp index fa672e68..fc086d1e 100644 --- a/src/gui2/imhex_overrides/main_menu_items.cpp +++ b/src/gui2/imhex_overrides/main_menu_items.cpp @@ -229,11 +229,11 @@ namespace hex::plugin::builtin { TaskManager::createTask("hex.builtin.task.exporting_data", TaskManager::NoProgress, [&formatter, path](auto&){ auto provider = ImHexApi::Provider::get(); auto selection = ImHexApi::HexEditor::getSelection() - .value_or( - ImHexApi::HexEditor::ProviderRegion { - { provider->getBaseAddress(), provider->getSize() }, - provider - }); + .value_or( + ImHexApi::HexEditor::ProviderRegion { + { provider->getBaseAddress(), provider->getSize() }, + provider + }); auto result = formatter.callback(provider, selection.getStartAddress(), selection.getSize(), false); @@ -412,16 +412,16 @@ namespace hex::plugin::builtin { ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.project" }, ICON_VS_NOTEBOOK, 1400, []{}, noRunningTasks); ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.open" }, ICON_VS_ROOT_FOLDER_OPENED, 1410, - CTRL + ALT + Keys::O + AllowWhileTyping, - openProject, noRunningTasks); + CTRL + ALT + Keys::O + AllowWhileTyping, + openProject, noRunningTasks); ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save" }, ICON_VS_SAVE, 1450, - CTRL + ALT + Keys::S + AllowWhileTyping, - saveProject, [&] { return noRunningTaskAndValidProvider() && ProjectFile::hasPath(); }); + CTRL + ALT + Keys::S + AllowWhileTyping, + saveProject, [&] { return noRunningTaskAndValidProvider() && ProjectFile::hasPath(); }); ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.project", "hex.builtin.menu.file.project.save_as" }, ICON_VS_SAVE_AS, 1500, - ALT + SHIFT + Keys::S + AllowWhileTyping, - saveProjectAs, noRunningTaskAndValidProvider); + ALT + SHIFT + Keys::S + AllowWhileTyping, + saveProjectAs, noRunningTaskAndValidProvider); ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 2000); @@ -432,21 +432,21 @@ namespace hex::plugin::builtin { /* IPS */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5150, - Shortcut::None, - importIPSPatch, - noRunningTaskAndWritableProvider); + Shortcut::None, + importIPSPatch, + noRunningTaskAndWritableProvider); /* IPS32 */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips32"}, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 5200, - Shortcut::None, - importIPS32Patch, - noRunningTaskAndWritableProvider); + Shortcut::None, + importIPS32Patch, + noRunningTaskAndWritableProvider); /* Modified File */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.modified_file" }, ICON_VS_FILES, 5300, - Shortcut::None, - importModifiedFile, - noRunningTaskAndWritableProvider); + Shortcut::None, + importModifiedFile, + noRunningTaskAndWritableProvider); } /* Export */ @@ -456,40 +456,40 @@ namespace hex::plugin::builtin { /* Selection to File */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.selection_to_file" }, ICON_VS_FILE_BINARY, 6010, - Shortcut::None, - exportSelectionToFile, - ImHexApi::HexEditor::isSelectionValid); + Shortcut::None, + exportSelectionToFile, + ImHexApi::HexEditor::isSelectionValid); /* Base 64 */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.base64" }, ICON_VS_NOTE, 6020, - Shortcut::None, - exportBase64, - isProviderDumpable); + Shortcut::None, + exportBase64, + isProviderDumpable); /* Language */ ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.as_language" }, ICON_VS_CODE, 6030, - drawExportLanguageMenu, - isProviderDumpable); + drawExportLanguageMenu, + isProviderDumpable); /* Report */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.report" }, ICON_VS_MARKDOWN, 6040, - Shortcut::None, - exportReport, - ImHexApi::Provider::isValid); + Shortcut::None, + exportReport, + ImHexApi::Provider::isValid); ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, 6050); /* IPS */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6100, - Shortcut::None, - exportIPSPatch, - isProviderDumpable); + Shortcut::None, + exportIPSPatch, + isProviderDumpable); /* IPS32 */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips32" }, ICON_VS_GIT_PULL_REQUEST_NEW_CHANGES, 6150, - Shortcut::None, - exportIPS32Patch, - isProviderDumpable); + Shortcut::None, + exportIPS32Patch, + isProviderDumpable); } ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 10000); @@ -513,41 +513,41 @@ namespace hex::plugin::builtin { ContentRegistry::UserInterface::registerMainMenuItem("hex.builtin.menu.view", 3000); #if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top" }, ICON_VS_PINNED, 1000, Keys::F10 + AllowWhileTyping, [] { - static bool state = false; + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.always_on_top" }, ICON_VS_PINNED, 1000, Keys::F10 + AllowWhileTyping, [] { + static bool state = false; - state = !state; - glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING, state); - }, []{ return true; }, []{ return glfwGetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); }); + state = !state; + glfwSetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING, state); + }, []{ return true; }, []{ return glfwGetWindowAttrib(ImHexApi::System::getMainWindowHandle(), GLFW_FLOATING); }); #endif #if !defined(OS_MACOS) && !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen" }, ICON_VS_SCREEN_FULL, 2000, Keys::F11 + AllowWhileTyping, [] { - static bool state = false; - static ImVec2 position, size; + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.view", "hex.builtin.menu.view.fullscreen" }, ICON_VS_SCREEN_FULL, 2000, Keys::F11 + AllowWhileTyping, [] { + static bool state = false; + static ImVec2 position, size; - state = !state; + state = !state; - const auto window = ImHexApi::System::getMainWindowHandle(); - if (state) { - position = ImHexApi::System::getMainWindowPosition(); - size = ImHexApi::System::getMainWindowSize(); + const auto window = ImHexApi::System::getMainWindowHandle(); + if (state) { + position = ImHexApi::System::getMainWindowPosition(); + size = ImHexApi::System::getMainWindowSize(); - const auto monitor = glfwGetPrimaryMonitor(); - const auto videoMode = glfwGetVideoMode(monitor); + const auto monitor = glfwGetPrimaryMonitor(); + const auto videoMode = glfwGetVideoMode(monitor); - glfwSetWindowMonitor(window, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); - } else { - glfwSetWindowMonitor(window, nullptr, position.x, position.y, size.x, size.y, 0); - glfwSetWindowAttrib(window, GLFW_DECORATED, ImHexApi::System::isBorderlessWindowModeEnabled() ? GLFW_FALSE : GLFW_TRUE); - } + glfwSetWindowMonitor(window, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); + } else { + glfwSetWindowMonitor(window, nullptr, position.x, position.y, size.x, size.y, 0); + glfwSetWindowAttrib(window, GLFW_DECORATED, ImHexApi::System::isBorderlessWindowModeEnabled() ? GLFW_FALSE : GLFW_TRUE); + } - }, []{ return true; }, []{ return glfwGetWindowMonitor(ImHexApi::System::getMainWindowHandle()) != nullptr; }); + }, []{ return true; }, []{ return glfwGetWindowMonitor(ImHexApi::System::getMainWindowHandle()) != nullptr; }); #endif #if !defined(OS_WEB) - ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.view" }, 3000); + ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.view" }, 3000); #endif ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.view" }, 4000, [] { From 971b1524624effebb67705f507510df958a826f4 Mon Sep 17 00:00:00 2001 From: Stephen Pick <3457029+the-claw@users.noreply.github.com> Date: Mon, 29 Jun 2026 12:10:12 +0100 Subject: [PATCH 4/4] Undo auto-reformatting of providers.cpp --- src/gui2/imhex_overrides/providers.cpp | 149 +++++++++---------------- 1 file changed, 52 insertions(+), 97 deletions(-) diff --git a/src/gui2/imhex_overrides/providers.cpp b/src/gui2/imhex_overrides/providers.cpp index f8e93cd2..c5797953 100644 --- a/src/gui2/imhex_overrides/providers.cpp +++ b/src/gui2/imhex_overrides/providers.cpp @@ -22,142 +22,98 @@ #include -namespace hex::plugin::builtin -{ +namespace hex::plugin::builtin { - void registerProviders() - { + void registerProviders() { ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); ContentRegistry::Provider::add(false); - ProjectFile::registerHandler({.basePath = "providers", + ProjectFile::registerHandler({ + .basePath = "providers", .required = true, - .load = - [](const std::fs::path& basePath, const Tar& tar) - { - auto json = nlohmann::json::parse( - tar.readString(basePath / "providers.json")); + .load = [](const std::fs::path &basePath, const Tar &tar) { + auto json = nlohmann::json::parse(tar.readString(basePath / "providers.json")); auto providerIds = json.at("providers").get>(); bool success = true; - std::map, std::string> - providerWarnings; - for (const auto& id : providerIds) - { - auto providerSettings = nlohmann::json::parse( - tar.readString(basePath / fmt::format("{}.json", id))); - - auto providerType = - providerSettings.at("type").get(); - auto newProvider = ImHexApi::Provider::createProvider( - providerType, true, false); - ON_SCOPE_EXIT - { - if (!success) - { - for (auto& task : TaskManager::getRunningTasks()) + std::map, std::string> providerWarnings; + for (const auto &id : providerIds) { + auto providerSettings = nlohmann::json::parse(tar.readString(basePath / fmt::format("{}.json", id))); + + auto providerType = providerSettings.at("type").get(); + auto newProvider = ImHexApi::Provider::createProvider(providerType, true, false); + ON_SCOPE_EXIT { + if (!success) { + for (auto &task : TaskManager::getRunningTasks()) task->interrupt(); - TaskManager::runWhenTasksFinished( - [] - { - for (const auto& provider : - ImHexApi::Provider::getProviders()) - ImHexApi::Provider::remove( - provider, true); - }); + TaskManager::runWhenTasksFinished([]{ + for (const auto &provider : ImHexApi::Provider::getProviders()) + ImHexApi::Provider::remove(provider, true); + }); } }; - if (newProvider == nullptr) - { - // If a provider is not created, it will be overwritten - // when saving the project, so we should prevent the - // project from loading at all - ui::ToastError::open(fmt::format( - "hex.builtin.popup.error.project.load"_lang, - fmt::format( - "hex.builtin.popup.error.project.load.create_provider"_lang, - providerType))); + if (newProvider == nullptr) { + // If a provider is not created, it will be overwritten when saving the project, + // so we should prevent the project from loading at all + ui::ToastError::open( + fmt::format("hex.builtin.popup.error.project.load"_lang, + fmt::format("hex.builtin.popup.error.project.load.create_provider"_lang, providerType) + ) + ); success = false; break; } newProvider->setID(id); bool loaded = false; - try - { - newProvider->loadSettings( - providerSettings.at("settings")); + try { + newProvider->loadSettings(providerSettings.at("settings")); loaded = true; + } catch (const std::exception &e){ + providerWarnings[newProvider] = e.what(); } - catch (const std::exception& e) - { - providerWarnings[newProvider] = e.what(); - } - if (loaded) - { + if (loaded) { auto openResult = newProvider->open(); - if (openResult.isFailure() || - !newProvider->isAvailable() || - !newProvider->isReadable()) - { - providerWarnings[newProvider] = - openResult.getErrorMessage(); - } - else - { + if (openResult.isFailure() || !newProvider->isAvailable() || !newProvider->isReadable()) { + providerWarnings[newProvider] = openResult.getErrorMessage(); + } else { EventProviderOpened::post(newProvider.get()); } } } std::string warningMessage; - for (const auto& warning : providerWarnings) - { + for (const auto &warning : providerWarnings){ ImHexApi::Provider::remove(warning.first.get()); - warningMessage.append(fmt::format("\n - {} : {}", - warning.first->getName(), - warning.second)); + warningMessage.append( + fmt::format("\n - {} : {}", warning.first->getName(), warning.second)); } // If no providers were opened, display an error with // the warnings that happened when opening them - if (ImHexApi::Provider::getProviders().empty()) - { - ui::ToastError::open(fmt::format("{}{}", - "hex.builtin.popup.error.project.load"_lang, - "hex.builtin.popup.error.project.load.no_providers"_lang, - warningMessage)); + if (ImHexApi::Provider::getProviders().empty()) { + ui::ToastError::open(fmt::format("{}{}", "hex.builtin.popup.error.project.load"_lang, "hex.builtin.popup.error.project.load.no_providers"_lang, warningMessage)); return false; - } - else - { + } else { // Else, if there are warnings, still display them - if (warningMessage.empty()) - { + if (warningMessage.empty()) { return true; - } - else - { - ui::ToastWarning::open(fmt::format( - "hex.builtin.popup.error.project.load.some_providers_failed"_lang, - warningMessage)); + } else { + ui::ToastWarning::open(fmt::format("hex.builtin.popup.error.project.load.some_providers_failed"_lang, warningMessage)); } return success; } }, - .store = - [](const std::fs::path& basePath, const Tar& tar) - { + .store = [](const std::fs::path &basePath, const Tar &tar) { std::vector providerIds; - for (const auto& provider : ImHexApi::Provider::getProviders()) - { + for (const auto &provider : ImHexApi::Provider::getProviders()) { auto id = provider->getID(); providerIds.push_back(id); @@ -165,18 +121,17 @@ namespace hex::plugin::builtin json["type"] = provider->getTypeName(); json["settings"] = provider->storeSettings({}); - tar.writeString( - basePath / fmt::format("{}.json", id), json.dump(4)); + tar.writeString(basePath / fmt::format("{}.json", id), json.dump(4)); } tar.writeString(basePath / "providers.json", - nlohmann::json({ - {"providers", providerIds} - }) - .dump(4)); + nlohmann::json({ { "providers", providerIds } }).dump(4) + ); return true; - }}); + } + }); } } +