1
0
mirror of synced 2025-02-06 14:14:22 +01:00

feat: Added workspaces

This commit is contained in:
WerWolv 2023-12-11 15:54:22 +01:00
parent cc4d61f8f5
commit 91230ba438
30 changed files with 273 additions and 67 deletions

@ -1 +1 @@
Subproject commit 80b297385a465ca085fd49d06e9505d945363651 Subproject commit cc1fcd7519bcb0d7f24a911a539fe8eedd2b8d4d

View File

@ -14,6 +14,7 @@ set(LIBIMHEX_SOURCES
source/api/project_file_manager.cpp source/api/project_file_manager.cpp
source/api/theme_manager.cpp source/api/theme_manager.cpp
source/api/layout_manager.cpp source/api/layout_manager.cpp
source/api/workspace_manager.cpp
source/api/achievement_manager.cpp source/api/achievement_manager.cpp
source/api/localization_manager.cpp source/api/localization_manager.cpp

View File

@ -292,7 +292,7 @@ namespace hex {
void setCategoryDescription(const std::string &unlocalizedCategory, const std::string &unlocalizedDescription); 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); void write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &value);
} }

View File

@ -25,11 +25,17 @@ namespace hex {
*/ */
static void load(const std::fs::path &path); 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 * @brief Load a layout from a string
* @param content Layout 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 * @brief Get a list of all layouts

View File

@ -0,0 +1,35 @@
#pragma once
#include <wolv/io/fs.hpp>
#include <map>
#include <string>
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<std::string, WorkspaceManager::Workspace> s_workspaces;
static decltype(s_workspaces)::iterator s_currentWorkspace;
};
}

View File

@ -50,6 +50,7 @@ namespace hex::fs {
Libraries, Libraries,
Nodes, Nodes,
Layouts, Layouts,
Workspaces,
END END
}; };

View File

@ -6,6 +6,7 @@
#include <imgui.h> #include <imgui.h>
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/api/imhex_api.hpp>
namespace hex { namespace hex {
@ -24,7 +25,7 @@ namespace hex {
s_layoutPathToLoad = path; s_layoutPathToLoad = path;
} }
void LayoutManager::loadString(const std::string &content) { void LayoutManager::loadFromString(const std::string &content) {
s_layoutStringToLoad = content; s_layoutStringToLoad = content;
} }
@ -54,6 +55,11 @@ namespace hex {
LayoutManager::reload(); LayoutManager::reload();
} }
std::string LayoutManager::saveToString() {
return ImGui::SaveIniSettingsToMemory();
}
std::vector<LayoutManager::Layout> LayoutManager::getLayouts() { std::vector<LayoutManager::Layout> LayoutManager::getLayouts() {
return s_layouts; return s_layouts;
} }

View File

@ -0,0 +1,102 @@
#include <hex/api/workspace_manager.hpp>
#include <hex/api/layout_manager.hpp>
#include <hex/helpers/logger.hpp>
#include <wolv/io/file.hpp>
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
namespace hex {
std::map<std::string, WorkspaceManager::Workspace> 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 = {};
}
}

View File

@ -423,6 +423,9 @@ namespace hex::fs {
case ImHexPath::Layouts: case ImHexPath::Layouts:
result = appendPath(getDataPaths(), "layouts"); result = appendPath(getDataPaths(), "layouts");
break; break;
case ImHexPath::Workspaces:
result = appendPath(getDataPaths(), "workspaces");
break;
} }
// Remove all paths that don't exist if requested // Remove all paths that don't exist if requested

View File

@ -14,8 +14,6 @@ struct ImGuiSettingsHandler;
namespace hex { namespace hex {
std::fs::path getImGuiSettingsPath();
void nativeErrorMessage(const std::string &message); void nativeErrorMessage(const std::string &message);
class Window { class Window {
@ -68,6 +66,8 @@ namespace hex {
bool m_frameRateTemporarilyUnlocked = false; bool m_frameRateTemporarilyUnlocked = false;
double m_frameRateUnlockTime = 0; double m_frameRateUnlockTime = 0;
bool m_anyViewsOpen = false;
ImGuiExt::ImHexCustomData m_imguiCustomData; ImGuiExt::ImHexCustomData m_imguiCustomData;
}; };

View File

@ -1,5 +1,6 @@
#include <hex/api/project_file_manager.hpp> #include <hex/api/project_file_manager.hpp>
#include <hex/api/task_manager.hpp> #include <hex/api/task_manager.hpp>
#include <hex/api/workspace_manager.hpp>
#include <init/tasks.hpp> #include <init/tasks.hpp>
@ -176,10 +177,7 @@ namespace hex::crash {
// Only do it when ImHex has finished its loading // Only do it when ImHex has finished its loading
EventImHexStartupFinished::subscribe([] { EventImHexStartupFinished::subscribe([] {
EventAbnormalTermination::subscribe([](int) { EventAbnormalTermination::subscribe([](int) {
// Save ImGui settings WorkspaceManager::exportToFile();
auto imguiSettingsPath = hex::getImGuiSettingsPath();
if (!imguiSettingsPath.empty())
ImGui::SaveIniSettingsToDisk(wolv::util::toUTF8String(imguiSettingsPath).c_str());
// Create crash backup if any providers are open // Create crash backup if any providers are open
if (ImHexApi::Provider::isValid()) { if (ImHexApi::Provider::isValid()) {

View File

@ -15,6 +15,7 @@
#include <hex/api/plugin_manager.hpp> #include <hex/api/plugin_manager.hpp>
#include <hex/api/layout_manager.hpp> #include <hex/api/layout_manager.hpp>
#include <hex/api/achievement_manager.hpp> #include <hex/api/achievement_manager.hpp>
#include <hex/api/workspace_manager.hpp>
#include <hex/ui/view.hpp> #include <hex/ui/view.hpp>
#include <hex/ui/popup.hpp> #include <hex/ui/popup.hpp>
@ -131,6 +132,7 @@ namespace hex::init {
ContentRegistry::Experiments::impl::getExperiments().clear(); ContentRegistry::Experiments::impl::getExperiments().clear();
ContentRegistry::Reports::impl::getGenerators().clear(); ContentRegistry::Reports::impl::getGenerators().clear();
WorkspaceManager::reset();
LayoutManager::reset(); LayoutManager::reset();
ThemeManager::reset(); ThemeManager::reset();

View File

@ -7,6 +7,8 @@
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/api/layout_manager.hpp> #include <hex/api/layout_manager.hpp>
#include <hex/api/shortcut_manager.hpp> #include <hex/api/shortcut_manager.hpp>
#include <hex/api/workspace_manager.hpp>
#include <hex/api/project_file_manager.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fs.hpp> #include <hex/helpers/fs.hpp>
@ -35,23 +37,12 @@
#include <fonts/codicons_font.h> #include <fonts/codicons_font.h>
#include <hex/api/project_file_manager.hpp>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
namespace hex { namespace hex {
using namespace std::literals::chrono_literals; 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() { Window::Window() {
stacktrace::initialize(); stacktrace::initialize();
@ -98,6 +89,9 @@ namespace hex {
EventAbnormalTermination::unsubscribe(this); EventAbnormalTermination::unsubscribe(this);
RequestOpenPopup::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->exitImGui();
this->exitGLFW(); this->exitGLFW();
} }
@ -764,6 +758,8 @@ namespace hex {
void Window::frame() { void Window::frame() {
auto &io = ImGui::GetIO(); auto &io = ImGui::GetIO();
this->m_anyViewsOpen = ImHexApi::Provider::isValid();
// Loop through all views and draw them // Loop through all views and draw them
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) { for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
ImGui::GetCurrentContext()->NextWindowData.ClearFlags(); ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
@ -856,6 +852,7 @@ namespace hex {
// Process layout load requests // Process layout load requests
// NOTE: This needs to be done before a new frame is started, otherwise ImGui won't handle docking correctly // NOTE: This needs to be done before a new frame is started, otherwise ImGui won't handle docking correctly
if (this->m_anyViewsOpen)
LayoutManager::process(); LayoutManager::process();
} }
@ -1200,16 +1197,6 @@ namespace hex {
ImGui::GetCurrentContext()->SettingsHandlers.push_back(handler); ImGui::GetCurrentContext()->SettingsHandlers.push_back(handler);
io.IniFilename = nullptr; 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() { void Window::exitImGui() {
ImGui::SaveIniSettingsToDisk(wolv::util::toUTF8String(s_imguiSettingsPath).c_str());
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
ImPlot::DestroyContext(); ImPlot::DestroyContext();

View File

@ -45,6 +45,7 @@ add_imhex_plugin(
source/content/report_generators.cpp source/content/report_generators.cpp
source/content/init_tasks.cpp source/content/init_tasks.cpp
source/content/fonts.cpp source/content/fonts.cpp
source/content/workspaces.cpp
source/content/data_processor_nodes/basic_nodes.cpp source/content/data_processor_nodes/basic_nodes.cpp
source/content/data_processor_nodes/control_nodes.cpp source/content/data_processor_nodes/control_nodes.cpp

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -246,8 +246,9 @@
"hex.builtin.menu.file.reload_provider": "Provider neu laden", "hex.builtin.menu.file.reload_provider": "Provider neu laden",
"hex.builtin.menu.help": "Hilfe", "hex.builtin.menu.help": "Hilfe",
"hex.builtin.menu.help.ask_for_help": "Dokumentation Fragen...", "hex.builtin.menu.help.ask_for_help": "Dokumentation Fragen...",
"hex.builtin.menu.layout": "Layout", "hex.builtin.menu.workspace": "Workspace",
"hex.builtin.menu.layout.save": "Layout speichern", "hex.builtin.menu.workspace.layout": "Layout",
"hex.builtin.menu.workspace.layout.save": "Layout speichern",
"hex.builtin.menu.view": "Ansicht", "hex.builtin.menu.view": "Ansicht",
"hex.builtin.menu.view.demo": "ImGui Demo anzeigen", "hex.builtin.menu.view.demo": "ImGui Demo anzeigen",
"hex.builtin.menu.view.fps": "FPS anzeigen", "hex.builtin.menu.view.fps": "FPS anzeigen",

View File

@ -268,9 +268,11 @@
"hex.builtin.menu.file.reload_provider": "Reload Provider", "hex.builtin.menu.file.reload_provider": "Reload Provider",
"hex.builtin.menu.help": "Help", "hex.builtin.menu.help": "Help",
"hex.builtin.menu.help.ask_for_help": "Ask Documentation...", "hex.builtin.menu.help.ask_for_help": "Ask Documentation...",
"hex.builtin.menu.layout": "Layout", "hex.builtin.menu.workspace": "Workspace",
"hex.builtin.menu.layout.lock": "Lock Layout", "hex.builtin.menu.workspace.create": "New Workspace...",
"hex.builtin.menu.layout.save": "Save Layout", "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": "View",
"hex.builtin.menu.view.debug": "Show Debugging View", "hex.builtin.menu.view.debug": "Show Debugging View",
"hex.builtin.menu.view.demo": "Show ImGui Demo", "hex.builtin.menu.view.demo": "Show ImGui Demo",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "Recargar Proveedor", "hex.builtin.menu.file.reload_provider": "Recargar Proveedor",
"hex.builtin.menu.help": "Ayuda", "hex.builtin.menu.help": "Ayuda",
"hex.builtin.menu.help.ask_for_help": "Preguntar Documentación...", "hex.builtin.menu.help.ask_for_help": "Preguntar Documentación...",
"hex.builtin.menu.layout": "Layout", "hex.builtin.menu.workspace.layout": "Layout",
"hex.builtin.menu.layout.save": "", "hex.builtin.menu.workspace.layout.save": "",
"hex.builtin.menu.view": "Vista", "hex.builtin.menu.view": "Vista",
"hex.builtin.menu.view.demo": "Mostrar Demo De ImGui", "hex.builtin.menu.view.demo": "Mostrar Demo De ImGui",
"hex.builtin.menu.view.fps": "Mostrar FPS", "hex.builtin.menu.view.fps": "Mostrar FPS",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.file.reload_provider": "",
"hex.builtin.menu.help": "Aiuto", "hex.builtin.menu.help": "Aiuto",
"hex.builtin.menu.help.ask_for_help": "", "hex.builtin.menu.help.ask_for_help": "",
"hex.builtin.menu.layout": "Layout", "hex.builtin.menu.workspace.layout": "Layout",
"hex.builtin.menu.layout.save": "", "hex.builtin.menu.workspace.layout.save": "",
"hex.builtin.menu.view": "Vista", "hex.builtin.menu.view": "Vista",
"hex.builtin.menu.view.demo": "Mostra la demo di ImGui", "hex.builtin.menu.view.demo": "Mostra la demo di ImGui",
"hex.builtin.menu.view.fps": "Mostra FPS", "hex.builtin.menu.view.fps": "Mostra FPS",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.file.reload_provider": "",
"hex.builtin.menu.help": "ヘルプ", "hex.builtin.menu.help": "ヘルプ",
"hex.builtin.menu.help.ask_for_help": "", "hex.builtin.menu.help.ask_for_help": "",
"hex.builtin.menu.layout": "レイアウト", "hex.builtin.menu.workspace.layout": "レイアウト",
"hex.builtin.menu.layout.save": "", "hex.builtin.menu.workspace.layout.save": "",
"hex.builtin.menu.view": "表示", "hex.builtin.menu.view": "表示",
"hex.builtin.menu.view.demo": "ImGuiデモを表示", "hex.builtin.menu.view.demo": "ImGuiデモを表示",
"hex.builtin.menu.view.fps": "FPSを表示", "hex.builtin.menu.view.fps": "FPSを表示",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "공급자 새로 고침", "hex.builtin.menu.file.reload_provider": "공급자 새로 고침",
"hex.builtin.menu.help": "도움말", "hex.builtin.menu.help": "도움말",
"hex.builtin.menu.help.ask_for_help": "설명서에 질문하기...", "hex.builtin.menu.help.ask_for_help": "설명서에 질문하기...",
"hex.builtin.menu.layout": "레이아웃", "hex.builtin.menu.workspace.layout": "레이아웃",
"hex.builtin.menu.layout.save": "레이아웃 저장", "hex.builtin.menu.workspace.layout.save": "레이아웃 저장",
"hex.builtin.menu.view": "보기", "hex.builtin.menu.view": "보기",
"hex.builtin.menu.view.demo": "ImGui 데모 표시", "hex.builtin.menu.view.demo": "ImGui 데모 표시",
"hex.builtin.menu.view.fps": "FPS 표시", "hex.builtin.menu.view.fps": "FPS 표시",
@ -1165,7 +1165,7 @@
"hex.builtin.pl_visualizer.3d.light_color": "조명 색상", "hex.builtin.pl_visualizer.3d.light_color": "조명 색상",
"hex.builtin.pl_visualizer.3d.more_settings": "설정 더 보기", "hex.builtin.pl_visualizer.3d.more_settings": "설정 더 보기",
"hex.builtin.pl_visualizer.3d.texture_file": "텍스처 파일 경로", "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.welcome.drop_file": "시작하려면 여기에 파일을 놓으세요...",
"hex.builtin.command.convert.desc": "단위 변환", "hex.builtin.command.convert.desc": "단위 변환",
"hex.builtin.command.convert.hexadecimal": "16진수", "hex.builtin.command.convert.hexadecimal": "16진수",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "", "hex.builtin.menu.file.reload_provider": "",
"hex.builtin.menu.help": "Ajuda", "hex.builtin.menu.help": "Ajuda",
"hex.builtin.menu.help.ask_for_help": "", "hex.builtin.menu.help.ask_for_help": "",
"hex.builtin.menu.layout": "Layout", "hex.builtin.menu.workspace.layout": "Layout",
"hex.builtin.menu.layout.save": "", "hex.builtin.menu.workspace.layout.save": "",
"hex.builtin.menu.view": "Exibir", "hex.builtin.menu.view": "Exibir",
"hex.builtin.menu.view.demo": "Mostrar Demo do ImGui", "hex.builtin.menu.view.demo": "Mostrar Demo do ImGui",
"hex.builtin.menu.view.fps": "Mostrar FPS", "hex.builtin.menu.view.fps": "Mostrar FPS",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "重载提供者", "hex.builtin.menu.file.reload_provider": "重载提供者",
"hex.builtin.menu.help": "帮助", "hex.builtin.menu.help": "帮助",
"hex.builtin.menu.help.ask_for_help": "查找文档...", "hex.builtin.menu.help.ask_for_help": "查找文档...",
"hex.builtin.menu.layout": "布局", "hex.builtin.menu.workspace.layout": "布局",
"hex.builtin.menu.layout.save": "保存布局", "hex.builtin.menu.workspace.layout.save": "保存布局",
"hex.builtin.menu.view": "视图", "hex.builtin.menu.view": "视图",
"hex.builtin.menu.view.demo": "ImGui 演示", "hex.builtin.menu.view.demo": "ImGui 演示",
"hex.builtin.menu.view.fps": "显示 FPS", "hex.builtin.menu.view.fps": "显示 FPS",

View File

@ -246,8 +246,8 @@
"hex.builtin.menu.file.reload_provider": "重新載入提供者", "hex.builtin.menu.file.reload_provider": "重新載入提供者",
"hex.builtin.menu.help": "幫助", "hex.builtin.menu.help": "幫助",
"hex.builtin.menu.help.ask_for_help": "問問說明文件...", "hex.builtin.menu.help.ask_for_help": "問問說明文件...",
"hex.builtin.menu.layout": "版面配置", "hex.builtin.menu.workspace.layout": "版面配置",
"hex.builtin.menu.layout.save": "儲存版面配置", "hex.builtin.menu.workspace.layout.save": "儲存版面配置",
"hex.builtin.menu.view": "檢視", "hex.builtin.menu.view": "檢視",
"hex.builtin.menu.view.demo": "顯示 ImGui Demo", "hex.builtin.menu.view.demo": "顯示 ImGui Demo",
"hex.builtin.menu.view.fps": "顯示 FPS", "hex.builtin.menu.view.fps": "顯示 FPS",

View File

@ -8,7 +8,7 @@ namespace hex::plugin::builtin {
void extractBundledFiles() { void extractBundledFiles() {
for (const auto &romfsPath : romfs::list("auto_extract")) { for (const auto &romfsPath : romfs::list("auto_extract")) {
for (const auto &imhexPath : fs::getDataPaths()) { 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()) if (!file.isValid())
continue; continue;

View File

@ -16,6 +16,7 @@
#include <content/global_actions.hpp> #include <content/global_actions.hpp>
#include <content/popups/popup_notification.hpp> #include <content/popups/popup_notification.hpp>
#include <content/popups/popup_text_input.hpp> #include <content/popups/popup_text_input.hpp>
#include <hex/api/workspace_manager.hpp>
#include <wolv/io/file.hpp> #include <wolv/io/file.hpp>
@ -540,28 +541,28 @@ namespace hex::plugin::builtin {
static void createLayoutMenu() { static void createLayoutMenu() {
LayoutManager::reload(); 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) { PopupTextInput::open("hex.builtin.popup.save_layout.title"_lang, "hex.builtin.popup.save_layout.desc"_lang, [](const std::string &name) {
LayoutManager::save(name); LayoutManager::save(name);
}); });
}, ImHexApi::Provider::isValid); }, 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(); 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); LayoutManager::lockLayout(locked);
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.layout_locked", 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")) { for (const auto &path : romfs::list("layouts")) {
if (ImGui::MenuItem(wolv::util::capitalizeString(path.stem().string()).c_str(), "", false, ImHexApi::Provider::isValid())) { 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() { static void createExtrasMenu() {
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.extras", 5000); ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.extras", 5000);
} }
@ -592,7 +616,7 @@ namespace hex::plugin::builtin {
createFileMenu(); createFileMenu();
createEditMenu(); createEditMenu();
createViewMenu(); createViewMenu();
createLayoutMenu(); createWorkspaceMenu();
createExtrasMenu(); createExtrasMenu();
createHelpMenu(); createHelpMenu();

View File

@ -30,6 +30,7 @@
#include <string> #include <string>
#include <random> #include <random>
#include <hex/api/workspace_manager.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -136,7 +137,7 @@ namespace hex::plugin::builtin {
}; };
void loadDefaultLayout() { void loadDefaultLayout() {
LayoutManager::loadString(std::string(romfs::get("layouts/default.hexlyt").string())); LayoutManager::loadFromString(std::string(romfs::get("layouts/default.hexlyt").string()));
} }
bool isAnyViewOpen() { bool isAnyViewOpen() {
@ -402,8 +403,10 @@ namespace hex::plugin::builtin {
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg)); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, windowSize); 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); ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen);
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
}
} }
ImGuiExt::EndSubWindow(); ImGuiExt::EndSubWindow();
ImGui::PopStyleColor(); ImGui::PopStyleColor();

View File

@ -0,0 +1,27 @@
#include <hex/api/content_registry.hpp>
#include <hex/api/workspace_manager.hpp>
#include <hex/helpers/fs.hpp>
#include <wolv/utils/guards.hpp>
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);
}
}

View File

@ -39,6 +39,7 @@ namespace hex::plugin::builtin {
void registerProjectHandlers(); void registerProjectHandlers();
void registerAchievements(); void registerAchievements();
void registerReportGenerators(); void registerReportGenerators();
void loadWorkspaces();
void addFooterItems(); void addFooterItems();
void addTitleBarButtons(); void addTitleBarButtons();
@ -79,6 +80,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
addInitTasks(); addInitTasks();
loadFonts(); loadFonts();
extractBundledFiles();
registerEventHandlers(); registerEventHandlers();
registerDataVisualizers(); registerDataVisualizers();
@ -107,6 +109,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
registerCommandForwarders(); registerCommandForwarders();
registerAchievements(); registerAchievements();
registerReportGenerators(); registerReportGenerators();
loadWorkspaces();
addFooterItems(); addFooterItems();
addTitleBarButtons(); addTitleBarButtons();
@ -116,8 +119,6 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
registerMainMenuEntries(); registerMainMenuEntries();
handleBorderlessWindowMode(); handleBorderlessWindowMode();
extractBundledFiles();
} }
// This is the default plugin // This is the default plugin