diff options
author | Vojtech Kral <vojtech@kral.hk> | 2018-08-06 19:26:29 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2018-09-14 16:10:50 +0300 |
commit | 7258c597b9140f09879db12ffc7334135b2d72d8 (patch) | |
tree | 88e97d7b396e5b722fdd7d56d2bd1e0348f02b6f /xs | |
parent | 8988e8cf0ac831307871eae226c77aedd7d06191 (diff) |
Fix window size persistence
Fixes #1116
Fixes #1175
Diffstat (limited to 'xs')
-rw-r--r-- | xs/src/slic3r/GUI/AppConfig.cpp | 8 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/AppConfig.hpp | 8 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/ConfigWizard.cpp | 9 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/GUI.cpp | 57 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/GUI.hpp | 8 | ||||
-rw-r--r-- | xs/xsp/GUI.xsp | 6 |
6 files changed, 89 insertions, 7 deletions
diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp index 2a33cd733..e66221351 100644 --- a/xs/src/slic3r/GUI/AppConfig.cpp +++ b/xs/src/slic3r/GUI/AppConfig.cpp @@ -60,6 +60,14 @@ void AppConfig::set_defaults() if (get("remember_output_path").empty()) set("remember_output_path", "1"); + + // Remove legacy window positions/sizes + erase("", "main_frame_maximized"); + erase("", "main_frame_pos"); + erase("", "main_frame_size"); + erase("", "object_settings_maximized"); + erase("", "object_settings_pos"); + erase("", "object_settings_size"); } void AppConfig::load() diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp index b742176ed..5af635a12 100644 --- a/xs/src/slic3r/GUI/AppConfig.hpp +++ b/xs/src/slic3r/GUI/AppConfig.hpp @@ -72,6 +72,14 @@ public: bool has(const std::string &key) const { return this->has("", key); } + void erase(const std::string §ion, const std::string &key) + { + auto it = m_storage.find(section); + if (it != m_storage.end()) { + it->second.erase(key); + } + } + void clear_section(const std::string §ion) { m_storage[section].clear(); } diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index bd9b9328a..e784d8525 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.cpp +++ b/xs/src/slic3r/GUI/ConfigWizard.cpp @@ -870,10 +870,11 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) : // If the screen is smaller, resize wizrad to match, which will enable scrollbars. auto wizard_size = GetSize(); unsigned width, height; - GUI::get_current_screen_size(width, height); - wizard_size.SetWidth(std::min(wizard_size.GetWidth(), (int)(width - 2 * DIALOG_MARGIN))); - wizard_size.SetHeight(std::min(wizard_size.GetHeight(), (int)(height - 2 * DIALOG_MARGIN))); - SetMinSize(wizard_size); + if (GUI::get_current_screen_size(this, width, height)) { + wizard_size.SetWidth(std::min(wizard_size.GetWidth(), (int)(width - 2 * DIALOG_MARGIN))); + wizard_size.SetHeight(std::min(wizard_size.GetHeight(), (int)(height - 2 * DIALOG_MARGIN))); + SetMinSize(wizard_size); + } Fit(); p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); }); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 8555f0b92..0272aae4e 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -7,6 +7,7 @@ #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> #include <boost/format.hpp> +#include <boost/lexical_cast.hpp> #if __APPLE__ #import <IOKit/pwr_mgt/IOPMLib.h> @@ -974,14 +975,66 @@ int get_export_option(wxFileDialog* dlg) } -void get_current_screen_size(unsigned &width, unsigned &height) +bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height) { - wxDisplay display(wxDisplay::GetFromWindow(g_wxMainFrame)); + const auto idx = wxDisplay::GetFromWindow(window); + if (idx == wxNOT_FOUND) { + return false; + } + + wxDisplay display(idx); const auto disp_size = display.GetClientArea(); width = disp_size.GetWidth(); height = disp_size.GetHeight(); + + return true; +} + +void save_window_size(wxTopLevelWindow *window, const std::string &name) +{ + const wxSize size = window->GetSize(); + const wxPoint pos = window->GetPosition(); + const auto maximized = window->IsMaximized() ? "1" : "0"; + + g_AppConfig->set((boost::format("window_%1%_size") % name).str(), (boost::format("%1%;%2%") % size.GetWidth() % size.GetHeight()).str()); + g_AppConfig->set((boost::format("window_%1%_maximized") % name).str(), maximized); +} + +void restore_window_size(wxTopLevelWindow *window, const std::string &name) +{ + // XXX: This still doesn't behave nicely in some situations (mostly on Linux). + // The problem is that it's hard to obtain window position with respect to screen geometry reliably + // from wxWidgets. Sometimes wxWidgets claim a window is located on a different screen than on which + // it's actually visible. I suspect this has something to do with window initialization (maybe we + // restore window geometry too early), but haven't yet found a workaround. + + const auto display_idx = wxDisplay::GetFromWindow(window); + if (display_idx == wxNOT_FOUND) { return; } + + const auto display = wxDisplay(display_idx).GetClientArea(); + std::vector<std::string> pair; + + try { + const auto key_size = (boost::format("window_%1%_size") % name).str(); + if (g_AppConfig->has(key_size)) { + if (unescape_strings_cstyle(g_AppConfig->get(key_size), pair) && pair.size() == 2) { + auto width = boost::lexical_cast<int>(pair[0]); + auto height = boost::lexical_cast<int>(pair[1]); + + window->SetSize(width, height); + } + } + } catch(const boost::bad_lexical_cast &) {} + + // Maximizing should be the last thing to do. + // This ensure the size and position are sane when the user un-maximizes the window. + const auto key_maximized = (boost::format("window_%1%_maximized") % name).str(); + if (g_AppConfig->get(key_maximized) == "1") { + window->Maximize(true); + } } + void about() { AboutDialog dlg; diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 165288819..68dbdfe84 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -24,6 +24,7 @@ class wxBoxSizer; class wxFlexGridSizer; class wxButton; class wxFileDialog; +class wxTopLevelWindow; namespace Slic3r { @@ -182,7 +183,12 @@ void add_export_option(wxFileDialog* dlg, const std::string& format); int get_export_option(wxFileDialog* dlg); // Returns the dimensions of the screen on which the main frame is displayed -void get_current_screen_size(unsigned &width, unsigned &height); +bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height); + +// Save window size and maximized status into AppConfig +void save_window_size(wxTopLevelWindow *window, const std::string &name); +// Restore the above +void restore_window_size(wxTopLevelWindow *window, const std::string &name); // Display an About dialog extern void about(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index c6eead1ad..8d2efb858 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -111,3 +111,9 @@ void register_on_request_update_callback(SV* callback) void deregister_on_request_update_callback() %code%{ Slic3r::GUI::g_on_request_update_callback.deregister_callback(); %}; +void save_window_size(SV *window, std::string name) + %code%{ Slic3r::GUI::save_window_size((wxTopLevelWindow*)wxPli_sv_2_object(aTHX_ window, "Wx::TopLevelWindow"), name); %}; + +void restore_window_size(SV *window, std::string name) + %code%{ Slic3r::GUI::restore_window_size((wxTopLevelWindow*)wxPli_sv_2_object(aTHX_ window, "Wx::TopLevelWindow"), name); %}; + |