diff --git a/glfw/glow-extras/glfw/GlfwApp.cc b/glfw/glow-extras/glfw/GlfwApp.cc index fb600f2ffef55f857332004fe5d7ccbaf345a0f1..d4f8123833028022d209fb937a6ac0876efe0e9a 100644 --- a/glfw/glow-extras/glfw/GlfwApp.cc +++ b/glfw/glow-extras/glfw/GlfwApp.cc @@ -244,7 +244,7 @@ void GlfwApp::init() if (mCacheWindowSize) { // Restore window size - std::ifstream file("glfwapp.ini"); + std::ifstream file(mCacheWindowSizeFilename); if (file.good()) { int w, h, x, y; @@ -755,7 +755,7 @@ void GlfwApp::internalCleanUp() if (mCacheWindowSize) { // Save window size to disk - std::ofstream file("glfwapp.ini"); + std::ofstream file(mCacheWindowSizeFilename); if (file.good()) { if (mInternalContext->isFullscreen()) diff --git a/glfw/glow-extras/glfw/GlfwApp.hh b/glfw/glow-extras/glfw/GlfwApp.hh index b490db6adc94cc01334bf5a70253dd8a80781861..d9ec6b75e5e6863a3b9d52484841da850107009f 100644 --- a/glfw/glow-extras/glfw/GlfwApp.hh +++ b/glfw/glow-extras/glfw/GlfwApp.hh @@ -130,6 +130,8 @@ private: bool mUsePipelineConfigGui = false; ///< if true, enables the pipeline scen configuration gui (only if pipeline is used, requires ImGui) bool mCacheWindowSize = false; ///< if true, saves window size and position on close, and restores on next launch + std::string mCacheWindowSizeFilename = "glfwapp.ini"; /// Default -> cwd + std::string mCacheWindowSizeFilenameImGui = "imgui.ini"; /// Default -> cwd double mCurrentTime = 0.0; ///< current frame time (starts with 0) double mCurrentRenderDeltaTime = 0.0; ///< current delta time for the render(dt) call @@ -226,6 +228,8 @@ public: GLOW_PROPERTY(UseDefaultCameraHandlingRight); GLOW_PROPERTY(CacheWindowSize); + GLOW_PROPERTY(CacheWindowSizeFilename); + GLOW_PROPERTY(CacheWindowSizeFilenameImGui); void setTitle(std::string const& title); diff --git a/viewer/glow-extras/viewer/ViewerApp.cc b/viewer/glow-extras/viewer/ViewerApp.cc index 4593c5082669d6601ff580915895ee888a219daf..1d804954166d275e828c0dc216291fcb3d00a0f8 100644 --- a/viewer/glow-extras/viewer/ViewerApp.cc +++ b/viewer/glow-extras/viewer/ViewerApp.cc @@ -178,10 +178,35 @@ void ViewerApp::init() if (mSettings.headlessScreenshot) setStartInvisible(true); + // set where to read and write the window position + // (empty location -> don't read or write) + if (mSettings.cacheWindowSizeFolder.empty()) + { + setCacheWindowSize(false); + } + else + { + setCacheWindowSize(true); + setCacheWindowSizeFilename(mSettings.cacheWindowSizeFolder + "glfwapp.ini"); + setCacheWindowSizeFilenameImGui(mSettings.cacheWindowSizeFolder + "imgui.ini"); + } + sLastCloseInfo.closed_by_key = -1; GlfwApp::init(); + // set where to read and write the window position; part 2 + // (ImGui Context has to be initialized already) + if (getGui() == Gui::ImGui) + { + if (!getCacheWindowSize()) + ImGui::GetIO().IniFilename = nullptr; + else + { + ImGui::GetIO().IniFilename = getCacheWindowSizeFilenameImGui().c_str(); + } + } + // create camera (before initial layout) // (or take preserved camera) bool newCamera; diff --git a/viewer/glow-extras/viewer/configure.cc b/viewer/glow-extras/viewer/configure.cc index b8ff0c10b257cac6741c887117ca4de01620e60e..856c72be61adbc68cff3de4c6cdff82e2049c389 100644 --- a/viewer/glow-extras/viewer/configure.cc +++ b/viewer/glow-extras/viewer/configure.cc @@ -258,6 +258,8 @@ void configure(GeometricRenderable& r, Picker p) r.setPicker(std::move(p)); } -void configure(Renderable&, const file_drop_handler& h) { detail::set_file_drop_handler(h.callback); } +void configure(Renderable&, file_drop_handler const& h) { detail::set_file_drop_handler(h.callback); } -} +void configure(Renderable&, cache_window_size const& s) { detail::set_cache_window_size_folder(s.folder); } + +} // namespace glow::viewer diff --git a/viewer/glow-extras/viewer/configure.hh b/viewer/glow-extras/viewer/configure.hh index 06fd71b2187a71d4ec10bde30402b1763ccee89e..e52660de8b0c8c49aef4a1bf39f29b36f5f2eade 100644 --- a/viewer/glow-extras/viewer/configure.hh +++ b/viewer/glow-extras/viewer/configure.hh @@ -156,6 +156,16 @@ struct file_drop_handler explicit file_drop_handler(std::function<void(std::vector<std::string> const&)> f) : callback(f) {} }; +struct cache_window_size +{ + std::string_view folder; + + constexpr explicit cache_window_size(std::string_view folder) + : folder(folder) + { + } +}; + // Config tags inline auto constexpr no_grid = no_grid_t{}; inline auto constexpr no_left_mouse_control = no_left_mouse_control_t{}; @@ -180,6 +190,7 @@ inline auto constexpr tonemap_exposure = tonemap_exposure_t{}; inline auto constexpr backface_culling = backface_culling_t{}; inline auto constexpr preserve_camera = preserve_camera_t{}; inline auto constexpr reuse_camera = reuse_camera_t{}; +inline auto constexpr no_cache_window_size = cache_window_size(""); // passthrough configures for scene modification commands void configure(Renderable&, no_grid_t b); @@ -217,6 +228,7 @@ void configure(Renderable&, close_keys const& k); void configure(Renderable&, preserve_camera_t b); void configure(Renderable&, reuse_camera_t b); void configure(Renderable&, file_drop_handler const& h); +void configure(Renderable&, cache_window_size const& h); /// custom scene configuration void configure(Renderable&, std::function<void(SceneConfig&)> f); diff --git a/viewer/glow-extras/viewer/detail/command_queue.cc b/viewer/glow-extras/viewer/detail/command_queue.cc index db9333da9bc0d5604f787694051dc23e79652089..7391eb3c9aff3864f412332801e295ee337403a7 100644 --- a/viewer/glow-extras/viewer/detail/command_queue.cc +++ b/viewer/glow-extras/viewer/detail/command_queue.cc @@ -1,5 +1,6 @@ #include "command_queue.hh" +#include <filesystem> #include <variant> #include <glow-extras/viewer/ViewerApp.hh> @@ -97,7 +98,7 @@ void glow::viewer::detail::on_last_command() } } -bool glow::viewer::detail::is_interactive(const glow::viewer::detail::command_queue& commands) +bool glow::viewer::detail::is_interactive(glow::viewer::detail::command_queue const& commands) { for (auto const& cmd : commands) if (cmd.instr == detail::command::instruction::InteractiveSubview) @@ -106,7 +107,7 @@ bool glow::viewer::detail::is_interactive(const glow::viewer::detail::command_qu return false; } -void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& rootNode, const glow::viewer::detail::command_queue& commands, float deltaTime, bool allowInteractiveExecute) +void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& rootNode, glow::viewer::detail::command_queue const& commands, float deltaTime, bool allowInteractiveExecute) { using cmd_t = detail::command; @@ -116,7 +117,7 @@ void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& r if (cmd.instr == cmd_t::instruction::AddRenderjob) { TG_ASSERT(currentNode != nullptr); - const auto renderable = cmd.data_renderable; + auto const renderable = cmd.data_renderable; TG_ASSERT(renderable); renderable->runLazyInit(); currentNode->scene.add(renderable); @@ -124,7 +125,7 @@ void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& r else if (cmd.instr == cmd_t::instruction::ModifyScene) { TG_ASSERT(currentNode != nullptr); - const auto funcp = cmd.data_scene; + auto const funcp = cmd.data_scene; TG_ASSERT(funcp); funcp(currentNode->scene); } @@ -159,7 +160,7 @@ void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& r else if (cmd.instr == cmd_t::instruction::ModifyLayout) { TG_ASSERT(currentNode != nullptr); - const auto layoutSettings = cmd.data_settings; + auto const layoutSettings = cmd.data_settings; currentNode->layoutSettings = layoutSettings; } else if (TG_LIKELY(cmd.instr == cmd_t::instruction::InteractiveSubview && allowInteractiveExecute)) @@ -173,7 +174,7 @@ void glow::viewer::detail::create_layout_tree(glow::viewer::layout::tree_node& r // Run the interactive lambda to fill innerCommandQueue { sCommandQueueStack.push_back(innerCommandQueue); - const auto funcp = cmd.data_interactive; + auto const funcp = cmd.data_interactive; TG_ASSERT(funcp); funcp(deltaTime); sCommandQueueStack.pop_back(); @@ -266,7 +267,6 @@ void glow::viewer::detail::reset_camera_to_scene(bool clip_cam) sCurrentViewerApp->resetCameraToSceneNextFrame(clip_cam); } - bool glow::viewer::detail::is_fullscreen() { if (nullptr == sCurrentViewerApp) @@ -288,7 +288,23 @@ void glow::viewer::detail::toggle_fullscreen() return sCurrentViewerApp->toggleFullscreen(); } -void glow::viewer::detail::set_file_drop_handler(std::function<void(const std::vector<std::string>&)> callback) +void glow::viewer::detail::set_file_drop_handler(std::function<void(std::vector<std::string> const&)> callback) { sGlobalSettings.onDropFiles = std::move(callback); } + +void glow::viewer::detail::set_cache_window_size_folder(std::string_view s) +{ + auto& folder = sGlobalSettings.cacheWindowSizeFolder; + folder = s; + if (folder.empty()) + return; + + if (folder.back() != '/') + folder.append("/"); + if (!std::filesystem::exists(folder)) + { + glow::warning() << "Target folder for window size caching does not exist! Defaulting to working directory."; + folder = "./"; + } +} diff --git a/viewer/glow-extras/viewer/detail/command_queue.hh b/viewer/glow-extras/viewer/detail/command_queue.hh index 38cb4be3c11ce24717ea02417b9fc207c3853175..196ec9e69c31f9f72f77837e0d5a83a319324178 100644 --- a/viewer/glow-extras/viewer/detail/command_queue.hh +++ b/viewer/glow-extras/viewer/detail/command_queue.hh @@ -31,6 +31,7 @@ struct global_settings bool rightMouseControlEnabled = true; bool enableViewerUI = true; + std::string cacheWindowSizeFolder = "./"; bool has3D = false; ///< True iff we have 3D content (this is set automatically) bool use_2d_controls() const { return controls2d_enabled || !has3D; } @@ -274,6 +275,7 @@ void set_subview_margin(int margin); void set_subview_margin_color(tg::color3 color); void set_headless_screenshot(tg::ivec2 resolution, int accum, std::string const& filename, GLenum format); void set_file_drop_handler(std::function<void(std::vector<std::string> const&)> callback); +void set_cache_window_size_folder(std::string_view s); // Returns true if the given command list contains one or more interactive instructions (and whose tree therefore must be rebuilt each frame) bool is_interactive(command_queue const& commands);