diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index b9f98e094..ac367a22e 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -59,20 +59,41 @@ public: { m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; - // ->- - m_prev_scale_factor = -1; - // -<- + m_prev_scale_factor = m_scale_factor; recalc_font(); this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { - // ->- - if (m_prev_scale_factor < 0) - reset_prev_scale_factor(); - // -<- - m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; - on_dpi_changed(evt.rect); + + if (!m_can_rescale) + return; + + if (is_new_scale_factor()) + rescale(evt.rect); + }); + + this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event) + { + event.Skip(); + + // Suppress application rescaling, when a MainFrame moving is not ended + m_can_rescale = false; + }); + + this->Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event) + { + event.Skip(); + + m_can_rescale = is_new_scale_factor(); + + // If scale factor is different after moving of MainFrame ... + if (m_can_rescale) + // ... rescale application + rescale(event.GetRect()); + else + // set value to _true_ in purpose of possibility of a display dpi changing from System Settings + m_can_rescale = true; }); } @@ -80,23 +101,21 @@ public: float scale_factor() const { return m_scale_factor; } float prev_scale_factor() const { return m_prev_scale_factor; } - void reset_prev_scale_factor() { m_prev_scale_factor = m_scale_factor; } + int em_unit() const { return m_em_unit; } int font_size() const { return m_font_size; } - protected: virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; - // ->- -// virtual void scale(wxWindow *window, const float& scale) = 0; - // -<- private: float m_scale_factor; - float m_prev_scale_factor; int m_em_unit; int m_font_size; + float m_prev_scale_factor; + bool m_can_rescale{ true }; + void recalc_font() { wxClientDC dc(this); @@ -104,6 +123,40 @@ private: m_font_size = metrics.height; m_em_unit = metrics.averageWidth; } + + // check if new scale is differ from previous + bool is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; } + + // recursive function for scaling fonts for all controls in Window + void scale_controls_fonts(wxWindow *window, const float scale_f) + { + auto children = window->GetChildren(); + + for (auto child : children) { + scale_controls_fonts(child, scale_f); + child->SetFont(child->GetFont().Scaled(scale_f)); + } + + window->Layout(); + } + + void rescale(const wxRect &suggested_rect) + { + this->Freeze(); + + // rescale fonts of all controls + scale_controls_fonts(this, m_scale_factor / m_prev_scale_factor); + + // rescale missed controls sizes and images + on_dpi_changed(suggested_rect); + + this->Layout(); + this->Thaw(); + + // reset previous scale factor from current scale factor value + m_prev_scale_factor = m_scale_factor; + } + }; typedef DPIAware DPIFrame; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 03dbb0c0d..17f423621 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -129,30 +129,6 @@ DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAU event.Skip(); }); - Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event) - { - event.Skip(); - - // Suppress application rescaling, when a MainFrame moving is not ended - m_can_rescale_application = false; - // Cash scale factor value before a MainFrame moving - m_scale_factor_cache = scale_factor(); - }); - - Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event) - { - event.Skip(); - - // If scale factor is different after moving of MainFrame ... - m_can_rescale_application = fabs(m_scale_factor_cache - scale_factor()) > 0.0001; - - // ... rescale application - on_dpi_changed(event.GetRect()); - - // set value to _true_ in purpose of possibility of a display dpi changing from System Settings - m_can_rescale_application = true; - }); - wxGetApp().persist_window_geometry(this); update_ui_from_settings(); // FIXME (?) @@ -280,62 +256,33 @@ bool MainFrame::can_delete_all() const return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false; } -// scale font for existing controls -static void scale_controls_fonts(wxWindow *window, const float scale_f) -{ - auto children = window->GetChildren(); - - for (auto child : children) - { - scale_controls_fonts(child, scale_f); - - child->SetFont(child->GetFont().Scaled(scale_f)); - } - window->Layout(); -} - void MainFrame::on_dpi_changed(const wxRect &suggested_rect) { - if (!m_can_rescale_application) - return; - - printf("WM_DPICHANGED: %.2f\n", scale_factor()); - const float old_sc_factor = prev_scale_factor(); const float new_sc_factor = scale_factor(); - if (fabs(old_sc_factor - new_sc_factor) > 0.001) - { - printf("\told_sc_factor: %.2f\n", old_sc_factor); - printf("\tnew_sc_factor: %.2f\n", new_sc_factor); + printf("old_sc_factor: %.2f \n", old_sc_factor); + printf("new_sc_factor: %.2f\n\n", new_sc_factor); - Freeze(); + const float relative_scale_factor = new_sc_factor / old_sc_factor; - scale_controls_fonts(this, new_sc_factor / old_sc_factor); - wxGetApp().scale_default_fonts(new_sc_factor / old_sc_factor); + wxGetApp().scale_default_fonts(relative_scale_factor); - const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor; - wxGetApp().set_em_unit(std::max(10, new_em_unit)); + // _strange_ workaround for correct em_unit calculation + const int new_em_unit = new_sc_factor * 10;//int(relative_scale_factor*wxGetApp().em_unit()); + wxGetApp().set_em_unit(std::max(10, new_em_unit)); - /* Load default preset bitmaps before a tabpanel initialization, - * but after filling of an em_unit value - */ - wxGetApp().preset_bundle->load_default_preset_bitmaps(this); + /* Load default preset bitmaps before a tabpanel initialization, + * but after filling of an em_unit value + */ + wxGetApp().preset_bundle->load_default_preset_bitmaps(this); - // update Plater - wxGetApp().plater()->rescale(); + // update Plater + wxGetApp().plater()->rescale(); - // update Tabs - for (auto tab : wxGetApp().tabs_list) - tab->rescale(); - - Layout(); - - Thaw(); - - Refresh(); - reset_prev_scale_factor(); - } + // update Tabs + for (auto tab : wxGetApp().tabs_list) + tab->rescale(); } void MainFrame::init_menubar() diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index b6d22f59a..a5d3a1f6d 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -44,8 +44,6 @@ struct PresetTab { class MainFrame : public DPIFrame { bool m_loaded {false}; - bool m_can_rescale_application {true}; - float m_scale_factor_cache; wxString m_qs_last_input_file = wxEmptyString; wxString m_qs_last_output_file = wxEmptyString;