From 370ca740e3e59837fd29ec11f9d3089682ae0e74 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 6 Dec 2023 13:49:58 +0100 Subject: [PATCH] feat: Allow layouts to be locked --- .../include/hex/api/layout_manager.hpp | 14 ++++++- lib/libimhex/source/api/layout_manager.cpp | 40 ++++++++++++++++--- main/gui/source/window/window.cpp | 15 +++++++ .../source/content/main_menu_items.cpp | 10 ++++- .../source/content/settings_entries.cpp | 7 ++++ 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/lib/libimhex/include/hex/api/layout_manager.hpp b/lib/libimhex/include/hex/api/layout_manager.hpp index adf37579f..4227aad6d 100644 --- a/lib/libimhex/include/hex/api/layout_manager.hpp +++ b/lib/libimhex/include/hex/api/layout_manager.hpp @@ -4,8 +4,6 @@ #include -#include - namespace hex { class LayoutManager { @@ -55,6 +53,18 @@ namespace hex { */ static void reset(); + /** + * @brief Checks is the current layout is locked + */ + static bool isLayoutLocked(); + + /** + * @brief Locks or unlocks the current layout + * @note If the layout is locked, it cannot be modified by the user anymore + * @param locked True to lock the layout, false to unlock it + */ + static void lockLayout(bool locked); + private: LayoutManager() = default; }; diff --git a/lib/libimhex/source/api/layout_manager.cpp b/lib/libimhex/source/api/layout_manager.cpp index 0dacdcfb7..6685f41c8 100644 --- a/lib/libimhex/source/api/layout_manager.cpp +++ b/lib/libimhex/source/api/layout_manager.cpp @@ -1,11 +1,11 @@ #include #include +#include #include #include - -#include +#include namespace hex { @@ -15,6 +15,8 @@ namespace hex { std::optional s_layoutStringToLoad; std::vector s_layouts; + bool s_layoutLocked = false; + } @@ -32,8 +34,22 @@ namespace hex { std::transform(fileName.begin(), fileName.end(), fileName.begin(), tolower); fileName += ".hexlyt"; - const auto path = hex::fs::getDefaultPaths(fs::ImHexPath::Layouts).front() / fileName; - ImGui::SaveIniSettingsToDisk(wolv::util::toUTF8String(path).c_str()); + std::fs::path layoutPath; + for (const auto &path : hex::fs::getDefaultPaths(fs::ImHexPath::Layouts)) { + if (!hex::fs::isPathWritable(layoutPath)) + continue; + + layoutPath = path / fileName; + } + + if (layoutPath.empty()) { + log::error("Failed to save layout '{}'. No writable path found", name); + return; + } + + const auto pathString = wolv::util::toUTF8String(layoutPath); + ImGui::SaveIniSettingsToDisk(pathString.c_str()); + log::info("Layout '{}' saved to {}", name, pathString); LayoutManager::reload(); } @@ -44,13 +60,16 @@ namespace hex { void LayoutManager::process() { if (s_layoutPathToLoad.has_value()) { - ImGui::LoadIniSettingsFromDisk(wolv::util::toUTF8String(*s_layoutPathToLoad).c_str()); + const auto pathString = wolv::util::toUTF8String(*s_layoutPathToLoad); + ImGui::LoadIniSettingsFromDisk(pathString.c_str()); s_layoutPathToLoad = std::nullopt; + log::info("Loaded layout from {}", pathString); } if (s_layoutStringToLoad.has_value()) { ImGui::LoadIniSettingsFromMemory(s_layoutStringToLoad->c_str()); s_layoutStringToLoad = std::nullopt; + log::info("Loaded layout from string"); } } @@ -85,4 +104,13 @@ namespace hex { s_layouts.clear(); } -} \ No newline at end of file + bool LayoutManager::isLayoutLocked() { + return s_layoutLocked; + } + + void LayoutManager::lockLayout(bool locked) { + log::info("Layout {}", locked ? "locked" : "unlocked"); + s_layoutLocked = locked; + } + +} diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index 454056d61..0f040afb2 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -793,6 +793,21 @@ namespace hex { if (!view->shouldProcess()) continue; + const auto openViewCount = std::ranges::count_if(ContentRegistry::Views::impl::getEntries(), [](const auto &entry) { + const auto &[unlocalizedName, view] = entry; + + return view->hasViewMenuItemEntry() && view->shouldProcess(); + }); + + ImGuiWindowClass windowClass = {}; + + windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoCloseButton; + + if (openViewCount <= 1 || LayoutManager::isLayoutLocked()) + windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoTabBar; + + ImGui::SetNextWindowClass(&windowClass); + // Draw view view->draw(); diff --git a/plugins/builtin/source/content/main_menu_items.cpp b/plugins/builtin/source/content/main_menu_items.cpp index 7f88707c9..8c3a78d13 100644 --- a/plugins/builtin/source/content/main_menu_items.cpp +++ b/plugins/builtin/source/content/main_menu_items.cpp @@ -521,7 +521,7 @@ namespace hex::plugin::builtin { if (view->hasViewMenuItemEntry()) { auto &state = view->getWindowOpenState(); - if (ImGui::MenuItem(Lang(view->getUnlocalizedName()), "", &state, ImHexApi::Provider::isValid())) + if (ImGui::MenuItem(Lang(view->getUnlocalizedName()), "", &state, ImHexApi::Provider::isValid() && !LayoutManager::isLayoutLocked())) view->setWindowJustOpened(state); } } @@ -548,6 +548,14 @@ namespace hex::plugin::builtin { }); }, ImHexApi::Provider::isValid); + ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.layout" }, 1150, [] { + bool locked = LayoutManager::isLayoutLocked(); + if (ImGui::MenuItem(locked ? "Unlock Layout" : "Lock Layout", nullptr, &locked)) { + 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::addMenuItemSubMenu({ "hex.builtin.menu.layout" }, 2000, [] { diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index a38eb6190..cb583fe8c 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -15,6 +15,7 @@ #include #include +#include #include namespace hex::plugin::builtin { @@ -489,6 +490,11 @@ namespace hex::plugin::builtin { } + static void loadLayoutSettings() { + const bool locked = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.layout_locked", false); + LayoutManager::lockLayout(locked); + } + static void loadThemeSettings() { auto theme = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.color", ThemeManager::NativeTheme).get(); @@ -512,6 +518,7 @@ namespace hex::plugin::builtin { } void loadSettings() { + loadLayoutSettings(); loadThemeSettings(); loadFolderSettings(); }