diff --git a/lib/external/libromfs b/lib/external/libromfs index 80b297385..cc1fcd751 160000 --- a/lib/external/libromfs +++ b/lib/external/libromfs @@ -1 +1 @@ -Subproject commit 80b297385a465ca085fd49d06e9505d945363651 +Subproject commit cc1fcd7519bcb0d7f24a911a539fe8eedd2b8d4d diff --git a/lib/libimhex/CMakeLists.txt b/lib/libimhex/CMakeLists.txt index 13b8f834e..42279482f 100644 --- a/lib/libimhex/CMakeLists.txt +++ b/lib/libimhex/CMakeLists.txt @@ -14,6 +14,7 @@ set(LIBIMHEX_SOURCES source/api/project_file_manager.cpp source/api/theme_manager.cpp source/api/layout_manager.cpp + source/api/workspace_manager.cpp source/api/achievement_manager.cpp source/api/localization_manager.cpp diff --git a/lib/libimhex/include/hex/api/content_registry.hpp b/lib/libimhex/include/hex/api/content_registry.hpp index dd4e4ee03..f65486795 100644 --- a/lib/libimhex/include/hex/api/content_registry.hpp +++ b/lib/libimhex/include/hex/api/content_registry.hpp @@ -292,7 +292,7 @@ namespace hex { void setCategoryDescription(const std::string &unlocalizedCategory, const std::string &unlocalizedDescription); - nlohmann::json read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &defaultValue); + [[nodiscard]] nlohmann::json read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &defaultValue); void write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &value); } diff --git a/lib/libimhex/include/hex/api/layout_manager.hpp b/lib/libimhex/include/hex/api/layout_manager.hpp index 4227aad6d..650f7cb4d 100644 --- a/lib/libimhex/include/hex/api/layout_manager.hpp +++ b/lib/libimhex/include/hex/api/layout_manager.hpp @@ -25,11 +25,17 @@ namespace hex { */ static void load(const std::fs::path &path); + /** + * @brief Saves the current layout to a string + * @return String containing the layout + */ + static std::string saveToString(); + /** * @brief Load a layout from a string * @param content Layout string */ - static void loadString(const std::string &content); + static void loadFromString(const std::string &content); /** * @brief Get a list of all layouts diff --git a/lib/libimhex/include/hex/api/workspace_manager.hpp b/lib/libimhex/include/hex/api/workspace_manager.hpp new file mode 100644 index 000000000..6657f764c --- /dev/null +++ b/lib/libimhex/include/hex/api/workspace_manager.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include +#include + +namespace hex { + + class WorkspaceManager { + public: + struct Workspace { + std::string layout; + std::fs::path path; + }; + + static void createWorkspace(const std::string &name, const std::string &layout = ""); + static void switchWorkspace(const std::string &name); + + static void importFromFile(const std::fs::path &path); + static bool exportToFile(std::fs::path path = {}); + + static const auto& getWorkspaces() { return s_workspaces; } + static const auto& getCurrentWorkspace() { return s_currentWorkspace; } + + static void reset(); + + private: + WorkspaceManager() = default; + + static std::map s_workspaces; + static decltype(s_workspaces)::iterator s_currentWorkspace; + }; + +} \ No newline at end of file diff --git a/lib/libimhex/include/hex/helpers/fs.hpp b/lib/libimhex/include/hex/helpers/fs.hpp index ce7daf12c..11fc4bd99 100644 --- a/lib/libimhex/include/hex/helpers/fs.hpp +++ b/lib/libimhex/include/hex/helpers/fs.hpp @@ -50,6 +50,7 @@ namespace hex::fs { Libraries, Nodes, Layouts, + Workspaces, END }; diff --git a/lib/libimhex/source/api/layout_manager.cpp b/lib/libimhex/source/api/layout_manager.cpp index 6685f41c8..2c065b2a4 100644 --- a/lib/libimhex/source/api/layout_manager.cpp +++ b/lib/libimhex/source/api/layout_manager.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace hex { @@ -24,7 +25,7 @@ namespace hex { s_layoutPathToLoad = path; } - void LayoutManager::loadString(const std::string &content) { + void LayoutManager::loadFromString(const std::string &content) { s_layoutStringToLoad = content; } @@ -54,6 +55,11 @@ namespace hex { LayoutManager::reload(); } + std::string LayoutManager::saveToString() { + return ImGui::SaveIniSettingsToMemory(); + } + + std::vector LayoutManager::getLayouts() { return s_layouts; } diff --git a/lib/libimhex/source/api/workspace_manager.cpp b/lib/libimhex/source/api/workspace_manager.cpp new file mode 100644 index 000000000..cbba55390 --- /dev/null +++ b/lib/libimhex/source/api/workspace_manager.cpp @@ -0,0 +1,102 @@ +#include +#include + +#include + +#include + +#include +#include + +namespace hex { + + std::map WorkspaceManager::s_workspaces; + decltype(WorkspaceManager::s_workspaces)::iterator WorkspaceManager::s_currentWorkspace = WorkspaceManager::s_workspaces.end(); + + void WorkspaceManager::createWorkspace(const std::string& name, const std::string &layout) { + s_workspaces[name] = Workspace { + .layout = layout.empty() ? LayoutManager::saveToString() : layout, + .path = {} + }; + + WorkspaceManager::switchWorkspace(name); + + for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Workspaces)) { + if (WorkspaceManager::exportToFile(path / (name + ".hexws"))) + break; + } + } + + void WorkspaceManager::switchWorkspace(const std::string& name) { + if (s_currentWorkspace != s_workspaces.end()) { + auto &[name, workspace] = *s_currentWorkspace; + workspace.layout = LayoutManager::saveToString(); + + WorkspaceManager::exportToFile(workspace.path); + } + + auto it = s_workspaces.find(name); + if (it == s_workspaces.end()) { + log::error("Failed to switch workspace. Workspace '{}' does not exist", name); + return; + } + + auto &[newName, newWorkspace] = *it; + s_currentWorkspace = it; + LayoutManager::loadFromString(newWorkspace.layout); + } + + void WorkspaceManager::importFromFile(const std::fs::path& path) { + wolv::io::File file(path, wolv::io::File::Mode::Read); + if (!file.isValid()) { + log::error("Failed to load workspace from file '{}'", path.string()); + return; + } + + auto content = file.readString(); + try { + auto json = nlohmann::json::parse(content.begin(), content.end()); + + std::string name = json["name"]; + std::string layout = json["layout"]; + + s_workspaces[name] = Workspace { + .layout = std::move(layout), + .path = path + }; + } catch (nlohmann::json::exception &e) { + log::error("Failed to load workspace from file '{}': {}", path.string(), e.what()); + } + } + + bool WorkspaceManager::exportToFile(std::fs::path path) { + if (path.empty()) { + if (s_currentWorkspace == s_workspaces.end()) + return false; + + path = s_currentWorkspace->second.path; + } + + wolv::io::File file(path, wolv::io::File::Mode::Create); + + if (!file.isValid()) + return false; + + nlohmann::json json; + json["name"] = s_currentWorkspace->first; + json["layout"] = LayoutManager::saveToString(); + + file.writeString(json.dump(4)); + + return true; + } + + + void WorkspaceManager::reset() { + s_workspaces.clear(); + s_currentWorkspace = {}; + } + + + +} diff --git a/lib/libimhex/source/helpers/fs.cpp b/lib/libimhex/source/helpers/fs.cpp index 2df51f9d3..ee64cde8a 100644 --- a/lib/libimhex/source/helpers/fs.cpp +++ b/lib/libimhex/source/helpers/fs.cpp @@ -423,6 +423,9 @@ namespace hex::fs { case ImHexPath::Layouts: result = appendPath(getDataPaths(), "layouts"); break; + case ImHexPath::Workspaces: + result = appendPath(getDataPaths(), "workspaces"); + break; } // Remove all paths that don't exist if requested diff --git a/main/gui/include/window.hpp b/main/gui/include/window.hpp index e8904aa8d..5d4ff6df8 100644 --- a/main/gui/include/window.hpp +++ b/main/gui/include/window.hpp @@ -14,8 +14,6 @@ struct ImGuiSettingsHandler; namespace hex { - std::fs::path getImGuiSettingsPath(); - void nativeErrorMessage(const std::string &message); class Window { @@ -68,6 +66,8 @@ namespace hex { bool m_frameRateTemporarilyUnlocked = false; double m_frameRateUnlockTime = 0; + bool m_anyViewsOpen = false; + ImGuiExt::ImHexCustomData m_imguiCustomData; }; diff --git a/main/gui/source/crash_handlers.cpp b/main/gui/source/crash_handlers.cpp index 46ac227dc..a6daf8a28 100644 --- a/main/gui/source/crash_handlers.cpp +++ b/main/gui/source/crash_handlers.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -176,10 +177,7 @@ namespace hex::crash { // Only do it when ImHex has finished its loading EventImHexStartupFinished::subscribe([] { EventAbnormalTermination::subscribe([](int) { - // Save ImGui settings - auto imguiSettingsPath = hex::getImGuiSettingsPath(); - if (!imguiSettingsPath.empty()) - ImGui::SaveIniSettingsToDisk(wolv::util::toUTF8String(imguiSettingsPath).c_str()); + WorkspaceManager::exportToFile(); // Create crash backup if any providers are open if (ImHexApi::Provider::isValid()) { diff --git a/main/gui/source/init/tasks.cpp b/main/gui/source/init/tasks.cpp index 2fb1a00d2..e91f8846b 100644 --- a/main/gui/source/init/tasks.cpp +++ b/main/gui/source/init/tasks.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -131,6 +132,7 @@ namespace hex::init { ContentRegistry::Experiments::impl::getExperiments().clear(); ContentRegistry::Reports::impl::getGenerators().clear(); + WorkspaceManager::reset(); LayoutManager::reset(); ThemeManager::reset(); diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index ab219831e..3b83f4ac7 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -35,23 +37,12 @@ #include -#include - #include namespace hex { using namespace std::literals::chrono_literals; - static std::fs::path s_imguiSettingsPath; - - /** - * @brief returns the path to load/save imgui settings to, or an empty path if no location was found - */ - std::fs::path getImGuiSettingsPath() { - return s_imguiSettingsPath; - } - Window::Window() { stacktrace::initialize(); @@ -98,6 +89,9 @@ namespace hex { EventAbnormalTermination::unsubscribe(this); RequestOpenPopup::unsubscribe(this); + WorkspaceManager::exportToFile(); + ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.curr_workspace", WorkspaceManager::getCurrentWorkspace()->first); + this->exitImGui(); this->exitGLFW(); } @@ -764,6 +758,8 @@ namespace hex { void Window::frame() { auto &io = ImGui::GetIO(); + this->m_anyViewsOpen = ImHexApi::Provider::isValid(); + // Loop through all views and draw them for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) { ImGui::GetCurrentContext()->NextWindowData.ClearFlags(); @@ -856,7 +852,8 @@ namespace hex { // Process layout load requests // NOTE: This needs to be done before a new frame is started, otherwise ImGui won't handle docking correctly - LayoutManager::process(); + if (this->m_anyViewsOpen) + LayoutManager::process(); } void Window::initGLFW() { @@ -1200,16 +1197,6 @@ namespace hex { ImGui::GetCurrentContext()->SettingsHandlers.push_back(handler); io.IniFilename = nullptr; - for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Config)) { - if (std::fs::exists(dir) && (fs::isPathWritable(dir))) { - s_imguiSettingsPath = dir / "interface.ini"; - break; - } - } - - if (!s_imguiSettingsPath.empty() && wolv::io::fs::exists(s_imguiSettingsPath)) { - ImGui::LoadIniSettingsFromDisk(wolv::util::toUTF8String(s_imguiSettingsPath).c_str()); - } } @@ -1250,8 +1237,6 @@ namespace hex { } void Window::exitImGui() { - ImGui::SaveIniSettingsToDisk(wolv::util::toUTF8String(s_imguiSettingsPath).c_str()); - ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImPlot::DestroyContext(); diff --git a/plugins/builtin/CMakeLists.txt b/plugins/builtin/CMakeLists.txt index d4f842773..94f19ed89 100644 --- a/plugins/builtin/CMakeLists.txt +++ b/plugins/builtin/CMakeLists.txt @@ -45,6 +45,7 @@ add_imhex_plugin( source/content/report_generators.cpp source/content/init_tasks.cpp source/content/fonts.cpp + source/content/workspaces.cpp source/content/data_processor_nodes/basic_nodes.cpp source/content/data_processor_nodes/control_nodes.cpp diff --git a/plugins/builtin/romfs/auto_extract/workspaces/default.hexws b/plugins/builtin/romfs/auto_extract/workspaces/default.hexws new file mode 100644 index 000000000..3a41308d9 --- /dev/null +++ b/plugins/builtin/romfs/auto_extract/workspaces/default.hexws @@ -0,0 +1,4 @@ +{ + "layout": "[Window][ImHexDockSpace]\nPos=0,19\nSize=1393,765\nCollapsed=0\n\n[Window][Debug##Default]\nPos=0,55\nSize=400,400\nCollapsed=0\n\n[Window][###hex.builtin.view.settings.name]\nPos=346,191\nSize=700,400\nCollapsed=0\n\n[Window][Question]\nPos=496,338\nSize=400,105\nCollapsed=0\n\n[Window][Welcome Screen]\nPos=0,37\nSize=1393,728\nCollapsed=0\n\n[Window][###hex.builtin.view.hex_editor.name]\nPos=0,38\nSize=619,468\nCollapsed=0\nDockId=0x00000007,0\n\n[Window][###hex.builtin.view.data_inspector.name]\nPos=621,38\nSize=124,468\nCollapsed=0\nDockId=0x00000008,0\n\n[Window][###hex.builtin.view.pattern_data.name]\nPos=0,508\nSize=745,252\nCollapsed=0\nDockId=0x00000006,0\n\n[Window][###hex.builtin.view.pattern_editor.name]\nPos=747,38\nSize=646,722\nCollapsed=0\nDockId=0x00000009,0\n\n[Window][###hex.builtin.view.hashes.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000009,4\n\n[Window][###hex.builtin.view.find.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000009,3\n\n[Window][###hex.builtin.view.bookmarks.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000009,2\n\n[Window][###hex.builtin.view.information.name]\nPos=-1889,-120\nSize=510,420\nCollapsed=0\n\n[Window][###hex.builtin.view.yara.name]\nPos=720,38\nSize=560,660\nCollapsed=0\n\n[Window][###hex.builtin.view.store.name]\nViewportPos=564,236\nViewportId=0xB51F9C4A\nSize=900,700\nCollapsed=0\n\n[Window][###hex.builtin.view.diff.name]\nPos=1372,38\nSize=1188,1333\nCollapsed=0\nDockId=0x00000009,1\n\n[Window][###hex.builtin.view.provider_settings.name]\nPos=822,38\nSize=637,720\nCollapsed=0\n\n[Window][###hex.builtin.view.provider_settings.load_popup]\nPos=585,322\nSize=314,208\nCollapsed=0\n\n[Window][###hex.builtin.view.patches.name]\nPos=-1889,-120\nSize=510,420\nCollapsed=0\n\n[Window][###hex.builtin.view.data_processor.name]\nPos=747,38\nSize=646,722\nCollapsed=0\nDockId=0x00000009,1\n\n[Window][###hex.builtin.view.tools.name]\nPos=849,268\nSize=431,430\nCollapsed=0\nDockId=0x0000000A,0\n\n[Window][###hex.builtin.view.theme_manager.name]\nPos=391,302\nSize=469,400\nCollapsed=0\n\n[Window][###hex.builtin.tools.invariant_multiplication]\nPos=-1826,300\nSize=600,232\nCollapsed=0\n\n[Window][###hex.builtin.tools.regex_replacer]\nPos=-2091,104\nSize=600,305\nCollapsed=0\n\n[Window][###hex.builtin.tools.calc]\nPos=-1811,118\nSize=600,402\nCollapsed=0\n\n[Window][###hex.builtin.tools.permissions]\nPos=423,296\nSize=600,220\nCollapsed=0\n\n[Window][###hex.builtin.view.help.about.name]\nPos=377,193\nSize=677,400\nCollapsed=0\n\n[Window][###hex.builtin.view.constants.name]\nPos=419,-124\nSize=652,660\nCollapsed=0\n\n[Window][###hex.builtin.view.disassembler.name]\nPos=1004,-204\nSize=1336,1320\nCollapsed=0\n\n[Window][##achievement_unlocked]\nPos=1093,0\nSize=200,55\nCollapsed=0\n\n[Window][hex.builtin.popup.blocking_task.title]\nPos=506,305\nSize=20,40\nCollapsed=0\n\n[Window][Waiting for Tasks]\nPos=60,60\nSize=16,35\nCollapsed=0\n\n[Window][Restore lost data]\nPos=555,349\nSize=283,84\nCollapsed=0\n\n[Window][Error]\nPos=440,301\nSize=400,118\nCollapsed=0\n\n[Window][###hex.builtin.view.highlight_rules.name]\nViewportPos=724,217\nViewportId=0x31C07F88\nSize=700,400\nCollapsed=0\n\n[Window][SideBarWindow]\nPos=19,37\nSize=660,1345\nCollapsed=0\n\n[Window][SideBarWindow/##Content_53A061AE]\nIsChild=1\nSize=644,1329\n\n[Window][Choose file]\nPos=382,131\nSize=516,458\nCollapsed=0\n\n[Window][###hex.builtin.view.logs.name]\nPos=60,60\nSize=549,466\nCollapsed=0\n\n[Window][###hex.builtin.view.achievements.name]\nPos=60,60\nSize=800,600\nCollapsed=0\n\n[Window][hex.builtin.welcome.start.recent.auto_backups]\nPos=580,365\nSize=233,52\nCollapsed=0\n\n[Window][Auto Backups]\nPos=580,331\nSize=233,120\nCollapsed=0\n\n[Window][hex.builtin.popup.create_workspace.title]\nPos=496,325\nSize=400,132\nCollapsed=0\n\n[Table][0x6A4694E4,3]\nRefScale=13\nColumn 0 Sort=0v\n\n[Table][0x7EE28D79,8]\nRefScale=13\nColumn 0 Width=13\nColumn 1 Weight=1.0000\nColumn 2 Weight=1.0000\nColumn 3 Weight=1.0000 Sort=0v\nColumn 4 Weight=1.0000\nColumn 5 Weight=1.0000\nColumn 6 Weight=1.0000\nColumn 7 Weight=1.0000\n\n[Table][0x6190819E,3]\nColumn 0 Weight=1.0000\nColumn 1 Weight=1.0000\nColumn 2 Weight=1.0000\n\n[Docking][Data]\nDockSpace ID=0x81A8BB71 Window=0xF9B0A590 Pos=225,133 Size=1393,722 Split=X\n DockNode ID=0x00000001 Parent=0x81A8BB71 SizeRef=1370,0 Split=Y\n DockNode ID=0x00000005 Parent=0x00000001 SizeRef=0,825 Split=X Selected=0x5708C63F\n DockNode ID=0x00000007 Parent=0x00000005 SizeRef=1140,701 Selected=0x5708C63F\n DockNode ID=0x00000008 Parent=0x00000005 SizeRef=228,701 Selected=0xFBA7A393\n DockNode ID=0x00000006 Parent=0x00000001 SizeRef=0,444 Selected=0x7AD1CDDD\n DockNode ID=0x00000002 Parent=0x81A8BB71 SizeRef=1188,0 Split=X\n DockNode ID=0x00000003 Parent=0x00000002 SizeRef=12,0\n DockNode ID=0x00000004 Parent=0x00000002 SizeRef=52,0 Split=Y Selected=0xCACA884B\n DockNode ID=0x00000009 Parent=0x00000004 SizeRef=420,228 Selected=0xCACA884B\n DockNode ID=0x0000000A Parent=0x00000004 SizeRef=420,430 Selected=0x1F041AD3\n\n[ImHex][General]\nhex.builtin.view.achievements.name=0\nhex.builtin.view.bookmarks.name=0\nhex.builtin.view.command_palette.name=0\nhex.builtin.view.constants.name=0\nhex.builtin.view.data_inspector.name=1\nhex.builtin.view.data_processor.name=1\nhex.builtin.view.diff.name=0\nhex.builtin.view.disassembler.name=0\nhex.builtin.view.find.name=0\nhex.builtin.view.hashes.name=0\nhex.builtin.view.help.about.name=0\nhex.builtin.view.hex_editor.name=1\nhex.builtin.view.highlight_rules.name=0\nhex.builtin.view.information.name=0\nhex.builtin.view.logs.name=0\nhex.builtin.view.patches.name=0\nhex.builtin.view.pattern_data.name=1\nhex.builtin.view.pattern_editor.name=1\nhex.builtin.view.provider_settings.name=0\nhex.builtin.view.settings.name=0\nhex.builtin.view.store.name=0\nhex.builtin.view.theme_manager.name=0\nhex.builtin.view.tools.name=0\nhex.builtin.view.yara.name=0\nhex.windows.view.tty_console.name=0\nhex.builtin.tools.demangler=0\nhex.builtin.tools.ascii_table=0\nhex.builtin.tools.regex_replacer=0\nhex.builtin.tools.color=0\nhex.builtin.tools.calc=0\nhex.builtin.tools.graphing=0\nhex.builtin.tools.base_converter=0\nhex.builtin.tools.byte_swapper=0\nhex.builtin.tools.permissions=0\nhex.builtin.tools.wiki_explain=0\nhex.builtin.tools.file_tools=0\nhex.builtin.tools.ieee754=0\nhex.builtin.tools.invariant_multiplication=0\nhex.builtin.tools.tcp_client_server=0\nhex.builtin.tools.euclidean_algorithm=0\n\n", + "name": "Default" +} \ No newline at end of file diff --git a/plugins/builtin/romfs/auto_extract/workspaces/minimal.hexws b/plugins/builtin/romfs/auto_extract/workspaces/minimal.hexws new file mode 100644 index 000000000..9619656fc --- /dev/null +++ b/plugins/builtin/romfs/auto_extract/workspaces/minimal.hexws @@ -0,0 +1,4 @@ +{ + "layout": "[Window][ImHexDockSpace]\nPos=0,19\nSize=600,783\nCollapsed=0\n\n[Window][Debug##Default]\nPos=0,55\nSize=400,400\nCollapsed=0\n\n[Window][###hex.builtin.view.settings.name]\nPos=259,200\nSize=700,400\nCollapsed=0\n\n[Window][Question]\nPos=496,338\nSize=400,105\nCollapsed=0\n\n[Window][Welcome Screen]\nPos=0,37\nSize=1393,728\nCollapsed=0\n\n[Window][###hex.builtin.view.hex_editor.name]\nPos=0,38\nSize=600,740\nCollapsed=0\nDockId=0x00000007,0\n\n[Window][###hex.builtin.view.data_inspector.name]\nPos=1142,76\nSize=553,980\nCollapsed=0\nDockId=0x00000008,0\n\n[Window][###hex.builtin.view.pattern_data.name]\nPos=0,1058\nSize=1695,445\nCollapsed=0\nDockId=0x00000006,0\n\n[Window][###hex.builtin.view.pattern_editor.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000004,0\n\n[Window][###hex.builtin.view.hashes.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000004,4\n\n[Window][###hex.builtin.view.find.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000004,3\n\n[Window][###hex.builtin.view.bookmarks.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000004,2\n\n[Window][###hex.builtin.view.information.name]\nPos=-1889,-120\nSize=510,420\nCollapsed=0\n\n[Window][###hex.builtin.view.yara.name]\nPos=720,38\nSize=560,660\nCollapsed=0\n\n[Window][###hex.builtin.view.store.name]\nPos=562,201\nSize=900,700\nCollapsed=0\n\n[Window][###hex.builtin.view.diff.name]\nPos=1233,38\nSize=687,1021\nCollapsed=0\n\n[Window][###hex.builtin.view.provider_settings.name]\nPos=822,38\nSize=637,720\nCollapsed=0\n\n[Window][###hex.builtin.view.provider_settings.load_popup]\nPos=585,322\nSize=314,208\nCollapsed=0\n\n[Window][###hex.builtin.view.patches.name]\nPos=-1889,-120\nSize=510,420\nCollapsed=0\n\n[Window][###hex.builtin.view.data_processor.name]\nPos=1697,76\nSize=863,1427\nCollapsed=0\nDockId=0x00000004,1\n\n[Window][###hex.builtin.view.tools.name]\nViewportPos=952,218\nViewportId=0x9B385D8A\nSize=1306,1600\nCollapsed=0\n\n[Window][###hex.builtin.view.theme_manager.name]\nPos=391,302\nSize=469,400\nCollapsed=0\n\n[Window][###hex.builtin.tools.invariant_multiplication]\nPos=-1826,300\nSize=600,232\nCollapsed=0\n\n[Window][###hex.builtin.tools.regex_replacer]\nPos=-2091,104\nSize=600,305\nCollapsed=0\n\n[Window][###hex.builtin.tools.calc]\nPos=-1811,118\nSize=600,402\nCollapsed=0\n\n[Window][###hex.builtin.tools.permissions]\nPos=423,296\nSize=600,220\nCollapsed=0\n\n[Window][###hex.builtin.view.help.about.name]\nPos=214,201\nSize=600,350\nCollapsed=0\n\n[Window][###hex.builtin.view.constants.name]\nPos=419,-124\nSize=652,660\nCollapsed=0\n\n[Window][###hex.builtin.view.disassembler.name]\nPos=1004,-204\nSize=1336,1320\nCollapsed=0\n\n[Window][##achievement_unlocked]\nPos=1093,0\nSize=200,55\nCollapsed=0\n\n[Window][hex.builtin.popup.blocking_task.title]\nPos=506,305\nSize=20,40\nCollapsed=0\n\n[Window][Waiting for Tasks]\nPos=60,60\nSize=16,35\nCollapsed=0\n\n[Window][Restore lost data]\nPos=555,349\nSize=283,84\nCollapsed=0\n\n[Window][Error]\nPos=440,301\nSize=400,118\nCollapsed=0\n\n[Window][###hex.builtin.view.highlight_rules.name]\nViewportPos=724,217\nViewportId=0x31C07F88\nSize=700,400\nCollapsed=0\n\n[Window][SideBarWindow]\nPos=19,37\nSize=660,1345\nCollapsed=0\n\n[Window][SideBarWindow/##Content_53A061AE]\nIsChild=1\nSize=644,1329\n\n[Window][Choose file]\nPos=382,131\nSize=516,458\nCollapsed=0\n\n[Window][###hex.builtin.view.logs.name]\nPos=60,60\nSize=549,466\nCollapsed=0\n\n[Window][###hex.builtin.view.achievements.name]\nPos=60,60\nSize=800,600\nCollapsed=0\n\n[Window][hex.builtin.welcome.start.recent.auto_backups]\nPos=580,365\nSize=233,52\nCollapsed=0\n\n[Window][Auto Backups]\nPos=580,331\nSize=233,120\nCollapsed=0\n\n[Window][hex.builtin.popup.create_workspace.title]\nPos=100,334\nSize=400,132\nCollapsed=0\n\n[Table][0x6A4694E4,3]\nRefScale=13\nColumn 0 Sort=0v\n\n[Table][0x7EE28D79,8]\nRefScale=13\nColumn 0 Width=13\nColumn 1 Weight=1.0000\nColumn 2 Weight=1.0000\nColumn 3 Weight=1.0000 Sort=0v\nColumn 4 Weight=1.0000\nColumn 5 Weight=1.0000\nColumn 6 Weight=1.0000\nColumn 7 Weight=1.0000\n\n[Table][0x6190819E,3]\nColumn 0 Weight=1.0000\nColumn 1 Weight=1.0000\nColumn 2 Weight=1.0000\n\n[Docking][Data]\nDockSpace ID=0x81A8BB71 Window=0xF9B0A590 Pos=220,131 Size=600,740 Split=X\n DockNode ID=0x00000001 Parent=0x81A8BB71 SizeRef=847,0 Split=Y\n DockNode ID=0x00000005 Parent=0x00000001 SizeRef=0,44 Split=X Selected=0x5708C63F\n DockNode ID=0x00000007 Parent=0x00000005 SizeRef=1140,701 Selected=0x5708C63F\n DockNode ID=0x00000008 Parent=0x00000005 SizeRef=553,701 Selected=0xFBA7A393\n DockNode ID=0x00000006 Parent=0x00000001 SizeRef=0,20 Selected=0x7AD1CDDD\n DockNode ID=0x00000002 Parent=0x81A8BB71 SizeRef=431,0 Split=X\n DockNode ID=0x00000003 Parent=0x00000002 SizeRef=12,0\n DockNode ID=0x00000004 Parent=0x00000002 SizeRef=52,0 Selected=0xCACA884B\n\n[ImHex][General]\nhex.builtin.view.achievements.name=0\nhex.builtin.view.bookmarks.name=0\nhex.builtin.view.command_palette.name=0\nhex.builtin.view.constants.name=0\nhex.builtin.view.data_inspector.name=0\nhex.builtin.view.data_processor.name=0\nhex.builtin.view.diff.name=0\nhex.builtin.view.disassembler.name=0\nhex.builtin.view.find.name=0\nhex.builtin.view.hashes.name=0\nhex.builtin.view.help.about.name=0\nhex.builtin.view.hex_editor.name=1\nhex.builtin.view.highlight_rules.name=0\nhex.builtin.view.information.name=0\nhex.builtin.view.logs.name=0\nhex.builtin.view.patches.name=0\nhex.builtin.view.pattern_data.name=0\nhex.builtin.view.pattern_editor.name=0\nhex.builtin.view.provider_settings.name=0\nhex.builtin.view.settings.name=0\nhex.builtin.view.store.name=0\nhex.builtin.view.theme_manager.name=0\nhex.builtin.view.tools.name=0\nhex.builtin.view.yara.name=0\nhex.windows.view.tty_console.name=0\nhex.builtin.tools.demangler=0\nhex.builtin.tools.ascii_table=0\nhex.builtin.tools.regex_replacer=0\nhex.builtin.tools.color=0\nhex.builtin.tools.calc=0\nhex.builtin.tools.graphing=0\nhex.builtin.tools.base_converter=0\nhex.builtin.tools.byte_swapper=0\nhex.builtin.tools.permissions=0\nhex.builtin.tools.wiki_explain=0\nhex.builtin.tools.file_tools=0\nhex.builtin.tools.ieee754=0\nhex.builtin.tools.invariant_multiplication=0\nhex.builtin.tools.tcp_client_server=0\nhex.builtin.tools.euclidean_algorithm=0\n\n", + "name": "Minimal" +} \ No newline at end of file diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index bb751dad0..fcd5a0834 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -246,8 +246,9 @@ "hex.builtin.menu.file.reload_provider": "Provider neu laden", "hex.builtin.menu.help": "Hilfe", "hex.builtin.menu.help.ask_for_help": "Dokumentation Fragen...", - "hex.builtin.menu.layout": "Layout", - "hex.builtin.menu.layout.save": "Layout speichern", + "hex.builtin.menu.workspace": "Workspace", + "hex.builtin.menu.workspace.layout": "Layout", + "hex.builtin.menu.workspace.layout.save": "Layout speichern", "hex.builtin.menu.view": "Ansicht", "hex.builtin.menu.view.demo": "ImGui Demo anzeigen", "hex.builtin.menu.view.fps": "FPS anzeigen", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 6dee9f216..3a360ee74 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -268,9 +268,11 @@ "hex.builtin.menu.file.reload_provider": "Reload Provider", "hex.builtin.menu.help": "Help", "hex.builtin.menu.help.ask_for_help": "Ask Documentation...", - "hex.builtin.menu.layout": "Layout", - "hex.builtin.menu.layout.lock": "Lock Layout", - "hex.builtin.menu.layout.save": "Save Layout", + "hex.builtin.menu.workspace": "Workspace", + "hex.builtin.menu.workspace.create": "New Workspace...", + "hex.builtin.menu.workspace.layout": "Layout", + "hex.builtin.menu.workspace.layout.lock": "Lock Layout", + "hex.builtin.menu.workspace.layout.save": "Save Layout", "hex.builtin.menu.view": "View", "hex.builtin.menu.view.debug": "Show Debugging View", "hex.builtin.menu.view.demo": "Show ImGui Demo", diff --git a/plugins/builtin/romfs/lang/es_ES.json b/plugins/builtin/romfs/lang/es_ES.json index 00cf23e19..4253cc1c6 100644 --- a/plugins/builtin/romfs/lang/es_ES.json +++ b/plugins/builtin/romfs/lang/es_ES.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "Recargar Proveedor", "hex.builtin.menu.help": "Ayuda", "hex.builtin.menu.help.ask_for_help": "Preguntar Documentación...", - "hex.builtin.menu.layout": "Layout", - "hex.builtin.menu.layout.save": "", + "hex.builtin.menu.workspace.layout": "Layout", + "hex.builtin.menu.workspace.layout.save": "", "hex.builtin.menu.view": "Vista", "hex.builtin.menu.view.demo": "Mostrar Demo De ImGui", "hex.builtin.menu.view.fps": "Mostrar FPS", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index 568bd2136..0631ae04f 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.help": "Aiuto", "hex.builtin.menu.help.ask_for_help": "", - "hex.builtin.menu.layout": "Layout", - "hex.builtin.menu.layout.save": "", + "hex.builtin.menu.workspace.layout": "Layout", + "hex.builtin.menu.workspace.layout.save": "", "hex.builtin.menu.view": "Vista", "hex.builtin.menu.view.demo": "Mostra la demo di ImGui", "hex.builtin.menu.view.fps": "Mostra FPS", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 70d4859a7..1cd41cb4d 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.help": "ヘルプ", "hex.builtin.menu.help.ask_for_help": "", - "hex.builtin.menu.layout": "レイアウト", - "hex.builtin.menu.layout.save": "", + "hex.builtin.menu.workspace.layout": "レイアウト", + "hex.builtin.menu.workspace.layout.save": "", "hex.builtin.menu.view": "表示", "hex.builtin.menu.view.demo": "ImGuiデモを表示", "hex.builtin.menu.view.fps": "FPSを表示", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index fa4e0c7b1..9458c1544 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "공급자 새로 고침", "hex.builtin.menu.help": "도움말", "hex.builtin.menu.help.ask_for_help": "설명서에 질문하기...", - "hex.builtin.menu.layout": "레이아웃", - "hex.builtin.menu.layout.save": "레이아웃 저장", + "hex.builtin.menu.workspace.layout": "레이아웃", + "hex.builtin.menu.workspace.layout.save": "레이아웃 저장", "hex.builtin.menu.view": "보기", "hex.builtin.menu.view.demo": "ImGui 데모 표시", "hex.builtin.menu.view.fps": "FPS 표시", @@ -1165,7 +1165,7 @@ "hex.builtin.pl_visualizer.3d.light_color": "조명 색상", "hex.builtin.pl_visualizer.3d.more_settings": "설정 더 보기", "hex.builtin.pl_visualizer.3d.texture_file": "텍스처 파일 경로", - "hex.builtin.menu.layout.lock": "레이아웃 잠금", + "hex.builtin.menu.workspace.layout.lock": "레이아웃 잠금", "hex.builtin.welcome.drop_file": "시작하려면 여기에 파일을 놓으세요...", "hex.builtin.command.convert.desc": "단위 변환", "hex.builtin.command.convert.hexadecimal": "16진수", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index 7738654a3..619e819ec 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.help": "Ajuda", "hex.builtin.menu.help.ask_for_help": "", - "hex.builtin.menu.layout": "Layout", - "hex.builtin.menu.layout.save": "", + "hex.builtin.menu.workspace.layout": "Layout", + "hex.builtin.menu.workspace.layout.save": "", "hex.builtin.menu.view": "Exibir", "hex.builtin.menu.view.demo": "Mostrar Demo do ImGui", "hex.builtin.menu.view.fps": "Mostrar FPS", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index 1da8235fe..9886cfcb2 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "重载提供者", "hex.builtin.menu.help": "帮助", "hex.builtin.menu.help.ask_for_help": "查找文档...", - "hex.builtin.menu.layout": "布局", - "hex.builtin.menu.layout.save": "保存布局", + "hex.builtin.menu.workspace.layout": "布局", + "hex.builtin.menu.workspace.layout.save": "保存布局", "hex.builtin.menu.view": "视图", "hex.builtin.menu.view.demo": "ImGui 演示", "hex.builtin.menu.view.fps": "显示 FPS", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index 518cb5a0e..f5e5f9cf8 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -246,8 +246,8 @@ "hex.builtin.menu.file.reload_provider": "重新載入提供者", "hex.builtin.menu.help": "幫助", "hex.builtin.menu.help.ask_for_help": "問問說明文件...", - "hex.builtin.menu.layout": "版面配置", - "hex.builtin.menu.layout.save": "儲存版面配置", + "hex.builtin.menu.workspace.layout": "版面配置", + "hex.builtin.menu.workspace.layout.save": "儲存版面配置", "hex.builtin.menu.view": "檢視", "hex.builtin.menu.view.demo": "顯示 ImGui Demo", "hex.builtin.menu.view.fps": "顯示 FPS", diff --git a/plugins/builtin/source/content/file_extraction.cpp b/plugins/builtin/source/content/file_extraction.cpp index 7fd628710..147d428a6 100644 --- a/plugins/builtin/source/content/file_extraction.cpp +++ b/plugins/builtin/source/content/file_extraction.cpp @@ -8,7 +8,7 @@ namespace hex::plugin::builtin { void extractBundledFiles() { for (const auto &romfsPath : romfs::list("auto_extract")) { for (const auto &imhexPath : fs::getDataPaths()) { - wolv::io::File file(imhexPath, wolv::io::File::Mode::Create); + wolv::io::File file(imhexPath / std::fs::relative(romfsPath, "auto_extract"), wolv::io::File::Mode::Create); if (!file.isValid()) continue; diff --git a/plugins/builtin/source/content/main_menu_items.cpp b/plugins/builtin/source/content/main_menu_items.cpp index f44e75206..aff91d370 100644 --- a/plugins/builtin/source/content/main_menu_items.cpp +++ b/plugins/builtin/source/content/main_menu_items.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -540,28 +541,28 @@ namespace hex::plugin::builtin { static void createLayoutMenu() { LayoutManager::reload(); - ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.layout", 4000); + ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.workspace", 4000); - ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.layout", "hex.builtin.menu.layout.save" }, 1100, Shortcut::None, [] { + ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout", "hex.builtin.menu.workspace.layout.save" }, 1100, Shortcut::None, [] { PopupTextInput::open("hex.builtin.popup.save_layout.title"_lang, "hex.builtin.popup.save_layout.desc"_lang, [](const std::string &name) { LayoutManager::save(name); }); }, ImHexApi::Provider::isValid); - ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.layout" }, 1150, [] { + ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 1150, [] { bool locked = LayoutManager::isLayoutLocked(); - if (ImGui::MenuItem("hex.builtin.menu.layout.lock"_lang, nullptr, &locked, ImHexApi::Provider::isValid())) { + if (ImGui::MenuItem("hex.builtin.menu.workspace.layout.lock"_lang, nullptr, &locked, ImHexApi::Provider::isValid())) { LayoutManager::lockLayout(locked); ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.layout_locked", locked); } }); - ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.layout" }, 1200); + ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 1200); - ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.layout" }, 2000, [] { + ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.layout" }, 2000, [] { for (const auto &path : romfs::list("layouts")) { if (ImGui::MenuItem(wolv::util::capitalizeString(path.stem().string()).c_str(), "", false, ImHexApi::Provider::isValid())) { - LayoutManager::loadString(std::string(romfs::get(path).string())); + LayoutManager::loadFromString(std::string(romfs::get(path).string())); } } @@ -579,6 +580,29 @@ namespace hex::plugin::builtin { }); } + static void createWorkspaceMenu() { + createLayoutMenu(); + + ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.workspace" }, 3000); + + ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.workspace", "hex.builtin.menu.workspace.create" }, 3100, Shortcut::None, [] { + PopupTextInput::open("hex.builtin.popup.create_workspace.title"_lang, "hex.builtin.popup.create_workspace.desc"_lang, [](const std::string &name) { + WorkspaceManager::createWorkspace(name); + }); + }, ImHexApi::Provider::isValid); + + ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.workspace" }, 3200, [] { + const auto &workspaces = WorkspaceManager::getWorkspaces(); + for (auto it = workspaces.begin(); it != workspaces.end(); ++it) { + const auto &[name, workspace] = *it; + + if (ImGui::MenuItem(name.c_str(), "", it == WorkspaceManager::getCurrentWorkspace(), ImHexApi::Provider::isValid())) { + WorkspaceManager::switchWorkspace(name); + } + } + }); + } + static void createExtrasMenu() { ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.extras", 5000); } @@ -592,7 +616,7 @@ namespace hex::plugin::builtin { createFileMenu(); createEditMenu(); createViewMenu(); - createLayoutMenu(); + createWorkspaceMenu(); createExtrasMenu(); createHelpMenu(); diff --git a/plugins/builtin/source/content/welcome_screen.cpp b/plugins/builtin/source/content/welcome_screen.cpp index b92a4f68d..fc202377e 100644 --- a/plugins/builtin/source/content/welcome_screen.cpp +++ b/plugins/builtin/source/content/welcome_screen.cpp @@ -30,6 +30,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -136,7 +137,7 @@ namespace hex::plugin::builtin { }; void loadDefaultLayout() { - LayoutManager::loadString(std::string(romfs::get("layouts/default.hexlyt").string())); + LayoutManager::loadFromString(std::string(romfs::get("layouts/default.hexlyt").string())); } bool isAnyViewOpen() { @@ -402,8 +403,10 @@ namespace hex::plugin::builtin { ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg)); ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, windowSize); { - if (ImGuiExt::ToggleSwitch("hex.builtin.welcome.quick_settings.simplified"_lang, &s_simplifiedWelcomeScreen)) + if (ImGuiExt::ToggleSwitch("hex.builtin.welcome.quick_settings.simplified"_lang, &s_simplifiedWelcomeScreen)) { ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen); + WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default"); + } } ImGuiExt::EndSubWindow(); ImGui::PopStyleColor(); diff --git a/plugins/builtin/source/content/workspaces.cpp b/plugins/builtin/source/content/workspaces.cpp new file mode 100644 index 000000000..242967861 --- /dev/null +++ b/plugins/builtin/source/content/workspaces.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include +#include + +namespace hex::plugin::builtin { + + void loadWorkspaces() { + for (const auto &defaultPath : fs::getDefaultPaths(fs::ImHexPath::Workspaces)) { + for (const auto &entry : std::fs::directory_iterator(defaultPath)) { + if (!entry.is_regular_file()) + continue; + + const auto &path = entry.path(); + if (path.extension() != ".hexws") + continue; + + WorkspaceManager::importFromFile(path); + } + } + + std::string currentWorkspace = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.curr_workspace", "Default"); + WorkspaceManager::switchWorkspace(currentWorkspace); + } + +} diff --git a/plugins/builtin/source/plugin_builtin.cpp b/plugins/builtin/source/plugin_builtin.cpp index 6748bd61d..b7cc3a155 100644 --- a/plugins/builtin/source/plugin_builtin.cpp +++ b/plugins/builtin/source/plugin_builtin.cpp @@ -39,6 +39,7 @@ namespace hex::plugin::builtin { void registerProjectHandlers(); void registerAchievements(); void registerReportGenerators(); + void loadWorkspaces(); void addFooterItems(); void addTitleBarButtons(); @@ -79,6 +80,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { addInitTasks(); loadFonts(); + extractBundledFiles(); registerEventHandlers(); registerDataVisualizers(); @@ -107,6 +109,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { registerCommandForwarders(); registerAchievements(); registerReportGenerators(); + loadWorkspaces(); addFooterItems(); addTitleBarButtons(); @@ -116,8 +119,6 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") { registerMainMenuEntries(); handleBorderlessWindowMode(); - - extractBundledFiles(); } // This is the default plugin