From 78c9ac21570a34084c3955ba33550cb9118e32b3 Mon Sep 17 00:00:00 2001 From: Dima Buzdyk Date: Tue, 23 Jul 2024 19:16:22 +0500 Subject: [PATCH 1/3] fix gizmo bar wobbling Gizmo bar is wobbling at specific application window width range. This comes from a bar scaling calculations method: - new scale calculated for already scaled bar - scale stored as application settings loosing precision Rework gizmo bar resizing code to remove feedback: - calculate scale factor based on unscaled bar size --- src/slic3r/GUI/GLCanvas3D.cpp | 33 ++++++++++------------- src/slic3r/GUI/GLToolbar.cpp | 26 ++++++++++++++---- src/slic3r/GUI/GLToolbar.hpp | 3 +++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 20 ++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 ++ 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 511bbfa6fce..9f5c2750bfb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7417,15 +7417,7 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() #if ENABLE_RETINA_GL const float sc = m_retina_helper->get_scale_factor() * scale; //BBS: GUI refactor: GLToolbar - m_main_toolbar.set_scale(sc); - m_assemble_view_toolbar.set_scale(sc); - m_separator_toolbar.set_scale(sc); - collapse_toolbar.set_scale(sc / 2.0); size *= m_retina_helper->get_scale_factor(); - - auto* m_notification = wxGetApp().plater()->get_notification_manager(); - m_notification->set_scale(sc); - m_gizmos.set_overlay_scale(sc); #else //BBS: GUI refactor: GLToolbar m_main_toolbar.set_icons_size(size); @@ -7437,18 +7429,13 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() //BBS: GUI refactor: GLToolbar #if BBS_TOOLBAR_ON_TOP - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0; + float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width_unscaled() : 0; + float top_tb_width = m_main_toolbar.get_width_unscaled() + m_gizmos.get_unscaled_total_width() + m_assemble_view_toolbar.get_width_unscaled() + m_separator_toolbar.get_width_unscaled() + collapse_toolbar_width; + float new_h_scale = cnv_size.get_width() / top_tb_width; - float top_tb_width = m_main_toolbar.get_width() + m_gizmos.get_scaled_total_width() + m_assemble_view_toolbar.get_width() + m_separator_toolbar.get_width() + collapse_toolbar_width * 2; - int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_gizmos.get_selectable_icons_cnt() + m_assemble_view_toolbar.get_visible_items_cnt() + m_separator_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt(); - float noitems_width = top_tb_width - size * items_cnt; // width of separators and borders in top toolbars - - // calculate scale needed for items in all top toolbars - float new_h_scale = (cnv_size.get_width() - noitems_width) / (items_cnt * GLToolbar::Default_Icons_Size); - - //for protect - if (new_h_scale <= 0) { - new_h_scale = 1; + // Limit upper size + if (new_h_scale > 1.2) { + new_h_scale = 1.2; } //use the same value as horizon @@ -7471,6 +7458,14 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() // set minimum scale as a auto scale for the toolbars float new_scale = std::min(new_h_scale, new_v_scale); #if ENABLE_RETINA_GL + m_main_toolbar.set_scale(new_scale); + m_assemble_view_toolbar.set_scale(new_scale); + m_separator_toolbar.set_scale(new_scale); + collapse_toolbar.set_scale(new_scale / 2.0); + auto* m_notification = wxGetApp().plater()->get_notification_manager(); + m_notification->set_scale(new_scale); + m_gizmos.set_overlay_scale(new_scale); + new_scale /= m_retina_helper->get_scale_factor(); #endif if (fabs(new_scale - scale) > 0.01) // scale is changed by 1% and more diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index be97e52e84a..ef4ec54fb32 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -395,10 +395,26 @@ float GLToolbar::get_width() if (m_layout.dirty) calc_layout(); - return m_layout.width; + return m_layout.width * m_layout.scale; } float GLToolbar::get_height() +{ + if (m_layout.dirty) + calc_layout(); + + return m_layout.height * m_layout.scale; +} + +float GLToolbar::get_width_unscaled() +{ + if (m_layout.dirty) + calc_layout(); + + return m_layout.width; +} + +float GLToolbar::get_height_unscaled() { if (m_layout.dirty) calc_layout(); @@ -682,7 +698,7 @@ float GLToolbar::get_width_horizontal() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; - return size * m_layout.scale; + return size; } //BBS: GUI refactor: GLToolbar @@ -704,12 +720,12 @@ float GLToolbar::get_width_vertical() const } } - return (2.0f * m_layout.border + m_layout.icons_size + max_extra_text_size) * m_layout.scale; + return (2.0f * m_layout.border + m_layout.icons_size + max_extra_text_size); } float GLToolbar::get_height_horizontal() const { - return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; + return (2.0f * m_layout.border + m_layout.icons_size); } float GLToolbar::get_height_vertical() const @@ -734,7 +750,7 @@ float GLToolbar::get_main_size() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; - return size * m_layout.scale; + return size; } int GLToolbar::get_visible_items_cnt() const diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 85413edc66d..9245402f702 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -386,6 +386,9 @@ class GLToolbar float get_width(); float get_height(); + float get_width_unscaled(); + float get_height_unscaled(); + void select_item(const std::string& name); bool is_item_pressed(const std::string& name) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 319c5c75f28..4c2a02e2791 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -1181,6 +1181,26 @@ float GLGizmosManager::get_scaled_total_width() const #endif } +float GLGizmosManager::get_unscaled_total_height() const +{ +//BBS: GUI refactor: to support top layout +#if BBS_TOOLBAR_ON_TOP + return 2.0f * m_layout.border + m_layout.icons_size; +#else + return (2.0f * m_layout.border + (float)get_selectable_idxs().size() * m_layout.stride_y() - m_layout.gap_y); +#endif +} + +float GLGizmosManager::get_unscaled_total_width() const +{ +//BBS: GUI refactor: to support top layout +#if BBS_TOOLBAR_ON_TOP + return (2.0f * m_layout.border + (float)get_selectable_idxs().size() * m_layout.stride_x() - m_layout.gap_x); +#else + return 2.0f * m_layout.border + m_layout.icons_size; +#endif +} + GLGizmoBase* GLGizmosManager::get_current() const { return ((m_current == Undefined) || m_gizmos.empty()) ? nullptr : m_gizmos[m_current].get(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 4511f021194..d12a79bb9a4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -293,6 +293,8 @@ class GLGizmosManager : public Slic3r::ObjectBase //BBS: GUI refactor: GLToolbar adjust float get_scaled_total_height() const; float get_scaled_total_width() const; + float get_unscaled_total_height() const; + float get_unscaled_total_width() const; GizmoObjectManipulation& get_object_manipulation() { return m_object_manipulation; } bool get_uniform_scaling() const { return m_object_manipulation.get_uniform_scaling();} From aa9c1ceec00da400c87521142e312e5aa3e1f0a1 Mon Sep 17 00:00:00 2001 From: Dima Buzdyk Date: Wed, 24 Jul 2024 16:16:18 +0500 Subject: [PATCH 2/3] rework gizmo bar scaling Unify scaling implementation across platforms (MacOS, Win, Linux). Now all platform scale bar setting icon size. Toolbar scale is used for high-DPI displays scaling only. --- src/slic3r/GUI/GLCanvas3D.cpp | 73 +++++++++++------------ src/slic3r/GUI/GLToolbar.cpp | 26 ++------ src/slic3r/GUI/GLToolbar.hpp | 3 - src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 20 ------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 - 5 files changed, 39 insertions(+), 85 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9f5c2750bfb..d277ed81109 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7403,39 +7403,33 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() return; } - float scale = wxGetApp().toolbar_icon_scale(); + /* Soolbar scale is a constant value which depends on display resolution and OS. */ + m_main_toolbar.set_scale(get_scale()); + m_assemble_view_toolbar.set_scale(get_scale()); + m_separator_toolbar.set_scale(get_scale()); + collapse_toolbar.set_scale(get_scale()); + auto* m_notification = wxGetApp().plater()->get_notification_manager(); + m_notification->set_scale(get_scale()); + m_gizmos.set_overlay_scale(get_scale()); + + float size = m_main_toolbar.get_icons_size(); Size cnv_size = get_canvas_size(); //BBS: GUI refactor: GLToolbar - int size_i = int(GLToolbar::Default_Icons_Size * scale); - // force even size - if (size_i % 2 != 0) - size_i -= 1; - float size = size_i; +#if BBS_TOOLBAR_ON_TOP + float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0; - // Set current size for all top toolbars. It will be used for next calculations -#if ENABLE_RETINA_GL - const float sc = m_retina_helper->get_scale_factor() * scale; - //BBS: GUI refactor: GLToolbar - size *= m_retina_helper->get_scale_factor(); -#else - //BBS: GUI refactor: GLToolbar - m_main_toolbar.set_icons_size(size); - m_assemble_view_toolbar.set_icons_size(size); - m_separator_toolbar.set_icons_size(size); - collapse_toolbar.set_icons_size(size / 2.0); - m_gizmos.set_overlay_icon_size(size); -#endif // ENABLE_RETINA_GL + float top_tb_width = m_main_toolbar.get_width() + m_gizmos.get_scaled_total_width() + m_assemble_view_toolbar.get_width() + m_separator_toolbar.get_width() + collapse_toolbar_width * 2; + int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_gizmos.get_selectable_icons_cnt() + m_assemble_view_toolbar.get_visible_items_cnt() + m_separator_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt(); + float noitems_width = top_tb_width - size * items_cnt; // width of separators and borders in top toolbars - //BBS: GUI refactor: GLToolbar -#if BBS_TOOLBAR_ON_TOP - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width_unscaled() : 0; - float top_tb_width = m_main_toolbar.get_width_unscaled() + m_gizmos.get_unscaled_total_width() + m_assemble_view_toolbar.get_width_unscaled() + m_separator_toolbar.get_width_unscaled() + collapse_toolbar_width; - float new_h_scale = cnv_size.get_width() / top_tb_width; + // calculate scale needed for items in all top toolbars + float new_h_scale = (cnv_size.get_width() - noitems_width) / (items_cnt * GLToolbar::Default_Icons_Size); + new_h_scale = std::min(new_h_scale, 1.f); - // Limit upper size - if (new_h_scale > 1.2) { - new_h_scale = 1.2; + //for protect + if (new_h_scale <= 0) { + new_h_scale = 1; } //use the same value as horizon @@ -7457,19 +7451,20 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() // set minimum scale as a auto scale for the toolbars float new_scale = std::min(new_h_scale, new_v_scale); -#if ENABLE_RETINA_GL - m_main_toolbar.set_scale(new_scale); - m_assemble_view_toolbar.set_scale(new_scale); - m_separator_toolbar.set_scale(new_scale); - collapse_toolbar.set_scale(new_scale / 2.0); - auto* m_notification = wxGetApp().plater()->get_notification_manager(); - m_notification->set_scale(new_scale); - m_gizmos.set_overlay_scale(new_scale); - new_scale /= m_retina_helper->get_scale_factor(); -#endif - if (fabs(new_scale - scale) > 0.01) // scale is changed by 1% and more - wxGetApp().set_auto_toolbar_icon_scale(new_scale); + //BBS: GUI refactor: GLToolbar + int size_i = int(GLToolbar::Default_Icons_Size * new_scale); + // force even size + if (size_i % 2 != 0) + size_i -= 1; + size = size_i; + + //BBS: GUI refactor: GLToolbar + m_main_toolbar.set_icons_size(size); + m_assemble_view_toolbar.set_icons_size(size); + m_separator_toolbar.set_icons_size(size); + collapse_toolbar.set_icons_size(size / 2.0); + m_gizmos.set_overlay_icon_size(size); } void GLCanvas3D::_render_overlays() diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index ef4ec54fb32..be97e52e84a 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -391,22 +391,6 @@ bool GLToolbar::add_separator() } float GLToolbar::get_width() -{ - if (m_layout.dirty) - calc_layout(); - - return m_layout.width * m_layout.scale; -} - -float GLToolbar::get_height() -{ - if (m_layout.dirty) - calc_layout(); - - return m_layout.height * m_layout.scale; -} - -float GLToolbar::get_width_unscaled() { if (m_layout.dirty) calc_layout(); @@ -414,7 +398,7 @@ float GLToolbar::get_width_unscaled() return m_layout.width; } -float GLToolbar::get_height_unscaled() +float GLToolbar::get_height() { if (m_layout.dirty) calc_layout(); @@ -698,7 +682,7 @@ float GLToolbar::get_width_horizontal() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; - return size; + return size * m_layout.scale; } //BBS: GUI refactor: GLToolbar @@ -720,12 +704,12 @@ float GLToolbar::get_width_vertical() const } } - return (2.0f * m_layout.border + m_layout.icons_size + max_extra_text_size); + return (2.0f * m_layout.border + m_layout.icons_size + max_extra_text_size) * m_layout.scale; } float GLToolbar::get_height_horizontal() const { - return (2.0f * m_layout.border + m_layout.icons_size); + return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; } float GLToolbar::get_height_vertical() const @@ -750,7 +734,7 @@ float GLToolbar::get_main_size() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; - return size; + return size * m_layout.scale; } int GLToolbar::get_visible_items_cnt() const diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 9245402f702..85413edc66d 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -386,9 +386,6 @@ class GLToolbar float get_width(); float get_height(); - float get_width_unscaled(); - float get_height_unscaled(); - void select_item(const std::string& name); bool is_item_pressed(const std::string& name) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 4c2a02e2791..319c5c75f28 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -1181,26 +1181,6 @@ float GLGizmosManager::get_scaled_total_width() const #endif } -float GLGizmosManager::get_unscaled_total_height() const -{ -//BBS: GUI refactor: to support top layout -#if BBS_TOOLBAR_ON_TOP - return 2.0f * m_layout.border + m_layout.icons_size; -#else - return (2.0f * m_layout.border + (float)get_selectable_idxs().size() * m_layout.stride_y() - m_layout.gap_y); -#endif -} - -float GLGizmosManager::get_unscaled_total_width() const -{ -//BBS: GUI refactor: to support top layout -#if BBS_TOOLBAR_ON_TOP - return (2.0f * m_layout.border + (float)get_selectable_idxs().size() * m_layout.stride_x() - m_layout.gap_x); -#else - return 2.0f * m_layout.border + m_layout.icons_size; -#endif -} - GLGizmoBase* GLGizmosManager::get_current() const { return ((m_current == Undefined) || m_gizmos.empty()) ? nullptr : m_gizmos[m_current].get(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index d12a79bb9a4..4511f021194 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -293,8 +293,6 @@ class GLGizmosManager : public Slic3r::ObjectBase //BBS: GUI refactor: GLToolbar adjust float get_scaled_total_height() const; float get_scaled_total_width() const; - float get_unscaled_total_height() const; - float get_unscaled_total_width() const; GizmoObjectManipulation& get_object_manipulation() { return m_object_manipulation; } bool get_uniform_scaling() const { return m_object_manipulation.get_uniform_scaling();} From 54ecc7359a3d94352d980a7b58f1823a34e8edf7 Mon Sep 17 00:00:00 2001 From: Dima Buzdyk Date: Sat, 3 Aug 2024 06:52:01 +0500 Subject: [PATCH 3/3] Add comments, reorganize changes to minimize diff --- src/slic3r/GUI/GLCanvas3D.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 961ff2d0942..0eca58fe58a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7400,17 +7400,21 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() return; } - /* Soolbar scale is a constant value which depends on display resolution and OS. */ - m_main_toolbar.set_scale(get_scale()); - m_assemble_view_toolbar.set_scale(get_scale()); - m_separator_toolbar.set_scale(get_scale()); - collapse_toolbar.set_scale(get_scale()); + Size cnv_size = get_canvas_size(); + + // Orca: Toolbar scale is a constant value which depends on display resolution and OS. + // Icon size is the only variable we change to scale the toolbars. + const float sc = get_scale(); + m_main_toolbar.set_scale(sc); + m_assemble_view_toolbar.set_scale(sc); + m_separator_toolbar.set_scale(sc); + collapse_toolbar.set_scale(sc); + auto* m_notification = wxGetApp().plater()->get_notification_manager(); - m_notification->set_scale(get_scale()); - m_gizmos.set_overlay_scale(get_scale()); + m_notification->set_scale(sc); + m_gizmos.set_overlay_scale(sc); float size = m_main_toolbar.get_icons_size(); - Size cnv_size = get_canvas_size(); //BBS: GUI refactor: GLToolbar #if BBS_TOOLBAR_ON_TOP @@ -7422,7 +7426,6 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() // calculate scale needed for items in all top toolbars float new_h_scale = (cnv_size.get_width() - noitems_width) / (items_cnt * GLToolbar::Default_Icons_Size); - new_h_scale = std::min(new_h_scale, 1.f); //for protect if (new_h_scale <= 0) { @@ -7448,15 +7451,16 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() // set minimum scale as a auto scale for the toolbars float new_scale = std::min(new_h_scale, new_v_scale); + new_scale = std::min(new_scale, 1.f); //BBS: GUI refactor: GLToolbar int size_i = int(GLToolbar::Default_Icons_Size * new_scale); - // force even size + // Orca: force even size if (size_i % 2 != 0) size_i -= 1; size = size_i; - //BBS: GUI refactor: GLToolbar + // Orca: set toolbar icon size regardless of platform m_main_toolbar.set_icons_size(size); m_assemble_view_toolbar.set_icons_size(size); m_separator_toolbar.set_icons_size(size);