From 3df1ed8f6b3dcda7f615db33bfee7eb721db8e5c Mon Sep 17 00:00:00 2001
From: Vojtech Kral <vojtech@kral.hk>
Date: Thu, 24 Jan 2019 13:16:46 +0100
Subject: [PATCH] Mac: Retina OpenGL: Fix ImGui font switch, dynamic switching,
 toolbar fixes

---
 src/slic3r/GUI/GLCanvas3D.cpp   | 25 ++++++++++++++++++++-----
 src/slic3r/GUI/GLCanvas3D.hpp   |  2 ++
 src/slic3r/GUI/GLToolbar.cpp    | 32 +++++++++++++++++++-------------
 src/slic3r/GUI/GUI_Preview.hpp  |  1 +
 src/slic3r/GUI/ImGuiWrapper.cpp |  2 ++
 src/slic3r/GUI/Plater.cpp       |  5 +++++
 src/slic3r/GUI/Preferences.cpp  |  3 +--
 7 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 4c71ff3d8..cfb7d3dce 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -3952,11 +3952,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
 
 #if ENABLE_RETINA_GL
         m_retina_helper.reset(new RetinaHelper(canvas));
-
-        const bool use_retina = wxGetApp().app_config->get("use_retina_opengl") == "1";
-        BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Use Retina OpenGL: " << use_retina;
-        m_retina_helper->set_use_retina(use_retina);
-        BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << m_retina_helper->get_scale_factor();
 #endif
     }
 
@@ -5947,6 +5942,26 @@ void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool foc
     }
 }
 
+void GLCanvas3D::update_ui_from_settings()
+{
+#if ENABLE_RETINA_GL
+    const float orig_scaling = m_retina_helper->get_scale_factor();
+
+    const bool use_retina = wxGetApp().app_config->get("use_retina_opengl") == "1";
+    BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Use Retina OpenGL: " << use_retina;
+    m_retina_helper->set_use_retina(use_retina);
+    const float new_scaling = m_retina_helper->get_scale_factor();
+
+    if (new_scaling != orig_scaling) {
+        BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling;
+
+        m_camera.zoom /= orig_scaling;
+        m_camera.zoom *= new_scaling;
+        _refresh_if_shown_on_screen();
+    }
+#endif
+}
+
 bool GLCanvas3D::_is_shown_on_screen() const
 {
     return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 5d9aafd80..0f998276d 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -1070,6 +1070,8 @@ public:
 
     void handle_sidebar_focus_event(const std::string& opt_key, bool focus_on);
 
+    void update_ui_from_settings();
+
 private:
     bool _is_shown_on_screen() const;
 #if !ENABLE_REWORKED_BED_SHAPE_CHANGE
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 8a9c12f26..e9ca9a6b1 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -468,12 +468,12 @@ float GLToolbar::get_width_horizontal() const
 
 float GLToolbar::get_width_vertical() const
 {
-    return 2.0f * m_layout.border + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
+    return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
 }
 
 float GLToolbar::get_height_horizontal() const
 {
-    return 2.0f * m_layout.border + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
+    return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
 }
 
 float GLToolbar::get_height_vertical() const
@@ -483,23 +483,25 @@ float GLToolbar::get_height_vertical() const
 
 float GLToolbar::get_main_size() const
 {
-    float size = 2.0f * m_layout.border;
+    float size = 2.0f * m_layout.border * m_layout.icons_scale;
     for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
     {
         if (m_items[i]->is_separator())
-            size += m_layout.separator_size;
+            size += m_layout.separator_size * m_layout.icons_scale;
         else
             size += (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale;
     }
 
     if (m_items.size() > 1)
-        size += ((float)m_items.size() - 1.0f) * m_layout.gap_size;
+        size += ((float)m_items.size() - 1.0f) * m_layout.gap_size * m_layout.icons_scale;
 
     return size;
 }
 
 std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
 {
+    // Note: m_layout.icons_scale is not applied here because mouse_pos is already in scaled coordinates
+
     float zoom = parent.get_camera_zoom();
     float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
 
@@ -591,6 +593,8 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
 
 std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent)
 {
+    // Note: m_layout.icons_scale is not applied here because mouse_pos is already in scaled coordinates
+
     float zoom = parent.get_camera_zoom();
     float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
 
@@ -774,11 +778,12 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
 
     float zoom = parent.get_camera_zoom();
     float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+    float factor = inv_zoom * m_layout.icons_scale;
 
-    float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * inv_zoom;
-    float scaled_separator_size = m_layout.separator_size * inv_zoom;
-    float scaled_gap_size = m_layout.gap_size * inv_zoom;
-    float scaled_border = m_layout.border * inv_zoom;
+    float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
+    float scaled_separator_size = m_layout.separator_size * factor;
+    float scaled_gap_size = m_layout.gap_size * factor;
+    float scaled_border = m_layout.border * factor;
     float scaled_width = get_width() * inv_zoom;
     float scaled_height = get_height() * inv_zoom;
 
@@ -899,11 +904,12 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
 
     float zoom = parent.get_camera_zoom();
     float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+    float factor = inv_zoom * m_layout.icons_scale;
 
-    float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * inv_zoom;
-    float scaled_separator_size = m_layout.separator_size * inv_zoom;
-    float scaled_gap_size = m_layout.gap_size * inv_zoom;
-    float scaled_border = m_layout.border * inv_zoom;
+    float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * factor;
+    float scaled_separator_size = m_layout.separator_size * factor;
+    float scaled_gap_size = m_layout.gap_size * factor;
+    float scaled_border = m_layout.border * factor;
     float scaled_width = get_width() * inv_zoom;
     float scaled_height = get_height() * inv_zoom;
 
diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp
index ccff885f2..d4410c589 100644
--- a/src/slic3r/GUI/GUI_Preview.hpp
+++ b/src/slic3r/GUI/GUI_Preview.hpp
@@ -109,6 +109,7 @@ public:
     virtual ~Preview();
 
     wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
+    GLCanvas3D* get_canvas3d() { return m_canvas; }
 
     void set_view_toolbar(GLToolbar* toolbar);
 
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index ed2654f51..2f231b2e1 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -205,6 +205,8 @@ void ImGuiWrapper::init_default_font(float scaling)
 {
     static const float font_size = 18.0f;
 
+    destroy_fonts_texture();
+
     ImGuiIO& io = ImGui::GetIO();
     io.Fonts->Clear();
     ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), font_size * scaling);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 530b64474..ee1473401 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1266,6 +1266,11 @@ void Plater::priv::update_ui_from_settings()
     //     $self->{buttons_sizer}->Show($self->{btn_reslice}, ! wxTheApp->{app_config}->get("background_processing"));
     //     $self->{buttons_sizer}->Layout;
     // }
+
+#if ENABLE_RETINA_GL
+    view3D->get_canvas3d()->update_ui_from_settings();
+    preview->get_canvas3d()->update_ui_from_settings();
+#endif
 }
 
 ProgressStatusBar* Plater::priv::statusbar()
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index 2aa5ecadd..b58ce5900 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -122,8 +122,7 @@ void PreferencesDialog::build()
 void PreferencesDialog::accept()
 {
 	if (m_values.find("no_defaults")       != m_values.end() ||
-		m_values.find("use_legacy_opengl") != m_values.end() ||
-		m_values.find("use_retina_opengl") != m_values.end()) {
+		m_values.find("use_legacy_opengl") != m_values.end()) {
 		warning_catcher(this, _(L("You need to restart Slic3r to make the changes effective.")));
 	}