From 3b9803ba6ec02c2471ff03c05a7df70e8e40cff5 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Tue, 16 Apr 2019 14:06:09 +0200
Subject: [PATCH] Fixed crash of build under OSX and Linux.

 + Added flag to control if application rescale is possible
---
 src/slic3r/GUI/Field.cpp     |  2 +-
 src/slic3r/GUI/GUI_App.cpp   |  2 +-
 src/slic3r/GUI/GUI_App.hpp   |  2 +-
 src/slic3r/GUI/GUI_Utils.hpp | 12 +++++----
 src/slic3r/GUI/MainFrame.cpp | 47 +++++++++++++++++++++++++++---------
 src/slic3r/GUI/MainFrame.hpp |  2 ++
 src/slic3r/GUI/Plater.cpp    |  3 ++-
 src/slic3r/GUI/Tab.cpp       |  7 +++---
 8 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index 80d2753ab..8a98a1ed7 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -846,7 +846,7 @@ void Choice::rescale()
 
     wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
 
-    const wxString selection = field->GetStringSelection();
+    const wxString selection = field->GetString(field->GetSelection());
 
 	/* To correct scaling (set new controll size) of a wxBitmapCombobox 
 	 * we need to refill control with new bitmaps. So, in our case : 
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index b0e585cb9..584a96a57 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -325,7 +325,7 @@ void GUI_App::init_fonts()
 #endif /*__WXMAC__*/
 }
 
-void GUI_App::scale_fonts(const float scale_f)
+void GUI_App::scale_default_fonts(const float scale_f)
 {
     m_small_font = m_small_font.Scaled(scale_f);
     m_bold_font = m_bold_font.Scaled(scale_f);
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 87c773164..8136973ae 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -98,7 +98,7 @@ public:
     void            init_label_colours();
     void            update_label_colours_from_appconfig();
     void            init_fonts();
-    void            scale_fonts(const float scale_f);
+    void            scale_default_fonts(const float scale_f);
     void            set_label_clr_modified(const wxColour& clr);
     void            set_label_clr_sys(const wxColour& clr);
 
diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp
index d68ac8b0d..b9f98e094 100644
--- a/src/slic3r/GUI/GUI_Utils.hpp
+++ b/src/slic3r/GUI/GUI_Utils.hpp
@@ -67,7 +67,8 @@ public:
 
         this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
             // ->-
-            m_prev_scale_factor = m_scale_factor;
+            if (m_prev_scale_factor < 0)
+                reset_prev_scale_factor();
             // -<-
 
             m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;
@@ -77,10 +78,11 @@ public:
 
     virtual ~DPIAware() {}
 
-    float scale_factor() const { return m_scale_factor; }
-    float prev_scale_factor() const { return m_prev_scale_factor; }
-    int em_unit() const { return m_em_unit; }
-    int font_size() const { return m_font_size; }
+    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:
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index b6fa3521d..03dbb0c0d 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -129,6 +129,30 @@ 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 (?)
@@ -257,37 +281,38 @@ bool MainFrame::can_delete_all() const
 }
 
 // scale font for existing controls
-static void scale(wxWindow *window, const float scale_f)
+static void scale_controls_fonts(wxWindow *window, const float scale_f)
 {
     auto children = window->GetChildren();
 
     for (auto child : children)
     {
-        scale(child, scale_f);
+        scale_controls_fonts(child, scale_f);
 
         child->SetFont(child->GetFont().Scaled(scale_f));
-
-//         const wxSize& sz = child->GetSize();
-//         if (sz != wxDefaultSize)
-//             child->SetSize(sz*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);
+
         Freeze();
 
-        scale(this, new_sc_factor / old_sc_factor);
-        wxGetApp().scale_fonts(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);
 
         const auto new_em_unit = wxGetApp().em_unit()*new_sc_factor / old_sc_factor;
         wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit));
@@ -309,8 +334,8 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect)
         Thaw();
 
         Refresh();
-    }
-    // -<-
+        reset_prev_scale_factor();
+    } 
 }
 
 void MainFrame::init_menubar()
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index a5d3a1f6d..b6d22f59a 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -44,6 +44,8 @@ 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;
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 4811b0555..93fbe263b 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -728,7 +728,8 @@ Sidebar::Sidebar(Plater *parent)
     // Buttons underneath the scrolled area
 
     auto init_btn = [this](wxButton **btn, wxString label) {
-        *btn = new wxButton(this, wxID_ANY, label);
+        *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, 
+                            wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
         (*btn)->SetFont(wxGetApp().bold_font());
     };
 
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 169a2dad7..4db781706 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -3203,10 +3203,11 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
 //                        mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png";
 //         }                               
 //         auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name));
+        int mode_id = int(options[0].opt.mode);
         const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap :
-                                 m_mode_bitmap_cache[int(options[0].opt.mode)].bmp();
+                                 m_mode_bitmap_cache[mode_id].bmp();
         auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap);
-        bmp->SetClientData((void*)options[0].opt.mode);
+        bmp->SetClientData((void*)&m_mode_bitmap_cache[mode_id]);
 
         bmp->SetBackgroundStyle(wxBG_STYLE_PAINT);
         return bmp;
@@ -3251,7 +3252,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
         if (ctrl == nullptr)
             return;
 
-        ctrl->SetBitmap(m_mode_bitmap_cache[reinterpret_cast<int>(ctrl->GetClientData())].bmp());
+        ctrl->SetBitmap(reinterpret_cast<PrusaBitmap*>(ctrl->GetClientData())->bmp());
     };
 
 	vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);