diff --git a/resources/icons/user.svg b/resources/icons/user.svg index b750021fc4..4b64970541 100644 --- a/resources/icons/user.svg +++ b/resources/icons/user.svg @@ -6,7 +6,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" - stroke="grey" + stroke="#808080" stroke-width="30" fill="none"> diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4b762a4496..5a84b6b84b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4302,7 +4302,7 @@ void GLCanvas3D::update_ui_from_settings() #endif // ENABLE_RETINA_GL if (wxGetApp().is_editor()) - wxGetApp().plater()->enable_collapse_toolbar(wxGetApp().app_config->get_bool("show_collapse_button")); + wxGetApp().plater()->enable_collapse_toolbar(wxGetApp().app_config->get_bool("show_collapse_button") || !wxGetApp().sidebar().IsShown()); } GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const @@ -5023,9 +5023,9 @@ bool GLCanvas3D::_init_main_toolbar() m_main_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); m_main_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Right); m_main_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Top); - m_main_toolbar.set_border(5.0f); - m_main_toolbar.set_separator_size(5); - m_main_toolbar.set_gap_size(4); + //m_main_toolbar.set_border(5.0f); + //m_main_toolbar.set_separator_size(5.f); + //m_main_toolbar.set_gap_size(5.f); GLToolbarItem::Data item; @@ -5164,7 +5164,9 @@ bool GLCanvas3D::_init_main_toolbar() item.icon_filename = "layers_white.svg"; item.tooltip = _u8L("Variable layer height"); item.sprite_id = sprite_id++; - item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; + item.left.action_callback = [this]() { + if (m_canvas != nullptr) + wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; item.visibility_callback = [this]()->bool { bool res = current_printer_technology() == ptFFF; // turns off if changing printer technology @@ -5207,9 +5209,9 @@ bool GLCanvas3D::_init_undoredo_toolbar() m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); m_undoredo_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Left); m_undoredo_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Top); - m_undoredo_toolbar.set_border(5.0f); - m_undoredo_toolbar.set_separator_size(5); - m_undoredo_toolbar.set_gap_size(4); + //m_undoredo_toolbar.set_border(5.f); + //m_undoredo_toolbar.set_separator_size(5.f); + //m_undoredo_toolbar.set_gap_size(5.f); GLToolbarItem::Data item; @@ -5972,34 +5974,41 @@ void GLCanvas3D::_render_sequential_clearance() m_sequential_print_clearance.render(); } -void GLCanvas3D::_check_and_update_toolbar_icon_scale() -{ - // Don't update a toolbar scale, when we are on a Preview - if (wxGetApp().plater()->is_preview_shown()) - return; - const float scale = wxGetApp().toolbar_icon_scale(); +bool GLCanvas3D::check_toolbar_icon_size(float init_scale, float& new_scale_to_save, int counter/* = 3*/) +{ const Size cnv_size = get_canvas_size(); - int size = int(GLToolbar::Default_Icons_Size * scale); - - // Set current size for all top toolbars. It will be used for next calculations - GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); #if ENABLE_RETINA_GL - const float sc = m_retina_helper->get_scale_factor() * scale; - m_main_toolbar.set_scale(sc); - m_undoredo_toolbar.set_scale(sc); - collapse_toolbar.set_scale(sc); - size *= int(m_retina_helper->get_scale_factor()); + float max_scale = m_retina_helper->get_scale_factor(); #else - m_main_toolbar.set_icons_size(size); - m_undoredo_toolbar.set_icons_size(size); - collapse_toolbar.set_icons_size(size); + float max_scale = 0.1f * wxGetApp().em_unit(); #endif // ENABLE_RETINA_GL + float scale = init_scale * max_scale; + + int size = int(GLToolbar::Default_Icons_Size * scale); + int gizmo_size = int(GLGizmosManager::Default_Icons_Size * scale); + + // Set current scale for all top toolbars. It will be used for next calculations + + GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); + GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar(); + + if (!is_approx(scale, m_main_toolbar.get_scale(), 0.015f)) { + m_main_toolbar.set_scale(scale); + m_undoredo_toolbar.set_scale(scale); + collapse_toolbar.set_scale(scale); + view_toolbar.set_scale(scale); + m_gizmos.set_overlay_scale(scale); + + view_toolbar.set_icons_size(gizmo_size); + } + const float top_tb_width = m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar.get_width(); - int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_undoredo_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt(); + float items_cnt = float(m_main_toolbar.get_visible_items_cnt() + m_undoredo_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt()); const float noitems_width = top_tb_width - float(size) * items_cnt; // width of separators and borders in top toolbars + items_cnt += 1.6; // +1.6 means a place for some minimal margin between toolbars // calculate scale needed for items in all top toolbars // the std::max() is there because on some Linux dialects/virtual machines this code is called when the canvas has not been properly initialized yet, @@ -6008,18 +6017,41 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() // https://github.com/supermerill/SuperSlicer/issues/854 const float new_h_scale = std::max((cnv_size.get_width() - noitems_width), 1.0f) / (items_cnt * GLToolbar::Default_Icons_Size); - items_cnt = m_gizmos.get_selectable_icons_cnt() + 3; // +3 means a place for top and view toolbars and separators in gizmos toolbar + float gizmos_height = m_gizmos.get_scaled_total_height(); + int giz_items_cnt = m_gizmos.get_selectable_icons_cnt(); + float noitems_height = gizmos_height - gizmo_size * giz_items_cnt; // height of separators and borders in gizmos toolbars - // calculate scale needed for items in the gizmos toolbar - const float new_v_scale = cnv_size.get_height() / (items_cnt * GLGizmosManager::Default_Icons_Size); + noitems_height += m_main_toolbar.get_height(); // increase its value to main_toolbar height + giz_items_cnt += 2; // +2 means a place for view toolbar + + const float new_v_scale = std::max((cnv_size.get_height() - noitems_height), 1.0f) / (giz_items_cnt * GLGizmosManager::Default_Icons_Size); // 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 - new_scale /= m_retina_helper->get_scale_factor(); -#endif - if (fabs(new_scale - scale) > 0.015) // scale is changed by 1.5% and more - wxGetApp().set_auto_toolbar_icon_scale(new_scale); + + new_scale_to_save = std::min(new_scale / max_scale, 1.f); + + if (is_approx(init_scale, new_scale_to_save, 0.015f) || counter == 0) + return true; + + // scale is changed by 1.5% and more + init_scale = new_scale_to_save; + counter--; + return check_toolbar_icon_size(init_scale, new_scale_to_save, counter); +} + + +void GLCanvas3D::_check_and_update_toolbar_icon_scale() +{ + // Don't update a toolbar scale, when we are on a Preview + if (wxGetApp().plater()->is_preview_shown()) + return; + + const float init_scale = wxGetApp().toolbar_icon_scale(); + float new_scale_to_save; + if (check_toolbar_icon_size(init_scale, new_scale_to_save) && + !is_approx(init_scale, new_scale_to_save, 0.015f)) + wxGetApp().set_auto_toolbar_icon_scale(new_scale_to_save); } void GLCanvas3D::_render_overlays() @@ -6087,17 +6119,6 @@ void GLCanvas3D::_render_volumes_for_picking(const Camera& camera) const void GLCanvas3D::_render_gizmos_overlay() { -#if ENABLE_RETINA_GL -// m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor()); - const float scale = m_retina_helper->get_scale_factor()*wxGetApp().toolbar_icon_scale(); - m_gizmos.set_overlay_scale(scale); //! #ys_FIXME_experiment -#else -// m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor()); -// m_gizmos.set_overlay_scale(wxGetApp().em_unit()*0.1f); - const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale()); - m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment -#endif /* __WXMSW__ */ - m_gizmos.render_overlay(); if (m_gizmo_highlighter.m_render_arrow) @@ -6156,19 +6177,6 @@ void GLCanvas3D::_render_view_toolbar() const { GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar(); -#if ENABLE_RETINA_GL - const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(); -#if __APPLE__ - view_toolbar.set_scale(scale); -#else // if GTK3 - const float size = int(GLGizmosManager::Default_Icons_Size * scale); - view_toolbar.set_icons_size(size); -#endif // __APPLE__ -#else - const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale()); - view_toolbar.set_icons_size(size); -#endif // ENABLE_RETINA_GL - const Size cnv_size = get_canvas_size(); // places the toolbar on the bottom-left corner of the 3d scene const float top = -0.5f * (float)cnv_size.get_height() + view_toolbar.get_height(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 783feb3a16..881f876c84 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1053,6 +1053,7 @@ private: void _render_gcode_cog() { m_gcode_viewer.render_cog(); } void _render_selection(); void _render_sequential_clearance(); + bool check_toolbar_icon_size(float init_scale, float& new_scale_to_save, int counter = 3); #if ENABLE_RENDER_SELECTION_CENTER void _render_selection_center() { m_selection.render_center(m_gizmos.is_dragging()); } #endif // ENABLE_RENDER_SELECTION_CENTER diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 651817324a..6d9af11956 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -96,7 +96,10 @@ void GLToolbarItem::render(const GLCanvas3D& parent, unsigned int tex_id, float GLTexture::Quad_UVs ret; // tiles in the texture are spaced by 1 pixel const float icon_size_px = (float)(tex_width - 1) / ((float)Num_States + (float)Num_Rendered_Highlight_States); - const char render_state = (m_highlight_state == NotHighlighted ? m_state : Num_States + m_highlight_state); + const char render_state = m_highlight_state == NotHighlighted ? + (m_state==Pressed ? Normal : // use regular icon, without black background + m_state==HoverPressed ? Hover : m_state ) : // use regular icon, without black background + Num_States + m_highlight_state; const float inv_tex_width = 1.0f / (float)tex_width; const float inv_tex_height = 1.0f / (float)tex_height; // tiles in the texture are spaced by 1 pixel @@ -142,7 +145,7 @@ BackgroundTexture::Metadata::Metadata() { } -const float GLToolbar::Default_Icons_Size = 40.0f; +const float GLToolbar::Default_Icons_Size = 36.f;// 40.0f; GLToolbar::Layout::Layout() : type(Horizontal) @@ -150,9 +153,9 @@ GLToolbar::Layout::Layout() , vertical_orientation(VO_Center) , top(0.0f) , left(0.0f) - , border(0.0f) - , separator_size(0.0f) - , gap_size(0.0f) + , border(5.0f) + , separator_size(5.0f) + , gap_size(6.0f) , icons_size(Default_Icons_Size) , scale(1.0f) , width(0.0f) @@ -253,6 +256,12 @@ void GLToolbar::set_scale(float scale) { if (m_layout.scale != scale) { m_layout.scale = scale; + + m_layout.icons_size = int(Default_Icons_Size * scale); + m_layout.border = int(5.f * scale); + m_layout.separator_size = int(5.f * scale); + m_layout.gap_size = int(6.f * scale); + m_layout.dirty = true; m_icons_texture_dirty = true; } @@ -556,12 +565,12 @@ float GLToolbar::get_width_horizontal() const float GLToolbar::get_width_vertical() const { - return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; + return (2.0f * (m_layout.border + m_layout.gap_size)) + m_layout.icons_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.gap_size)) + m_layout.icons_size; } float GLToolbar::get_height_vertical() const @@ -578,15 +587,12 @@ float GLToolbar::get_main_size() const continue; if (m_items[i]->is_separator()) - size += m_layout.separator_size; + size += m_layout.separator_size + m_layout.gap_size; else - size += (float)m_layout.icons_size; + size += (float)m_layout.icons_size + 2.f * m_layout.gap_size; } - 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 @@ -672,16 +678,16 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D const Size cnv_size = parent.get_canvas_size(); const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); - const float icons_size = m_layout.icons_size * m_layout.scale; - const float separator_size = m_layout.separator_size * m_layout.scale; - const float gap_size = m_layout.gap_size * m_layout.scale; - const float border = m_layout.border * m_layout.scale; + const float icons_size = m_layout.icons_size; + const float separator_size = m_layout.separator_size; + const float gap_size = m_layout.gap_size; + const float border = m_layout.border; const float separator_stride = separator_size + gap_size; - const float icon_stride = icons_size + gap_size; + const float icon_stride = icons_size + 2 * gap_size; float left = m_layout.left + border; - float top = m_layout.top - border; + float top = m_layout.top - border - gap_size; for (GLToolbarItem* item : m_items) { if (!item->is_visible()) @@ -771,16 +777,16 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& const Size cnv_size = parent.get_canvas_size(); const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); - const float icons_size = m_layout.icons_size * m_layout.scale; - const float separator_size = m_layout.separator_size * m_layout.scale; - const float gap_size = m_layout.gap_size * m_layout.scale; - const float border = m_layout.border * m_layout.scale; + const float icons_size = m_layout.icons_size; + const float separator_size = m_layout.separator_size; + const float gap_size = m_layout.gap_size; + const float border = m_layout.border; const float separator_stride = separator_size + gap_size; const float icon_stride = icons_size + gap_size; - float left = m_layout.left + border; - float top = m_layout.top - border; + float left = m_layout.left + border + gap_size; + float top = m_layout.top - border - gap_size; for (GLToolbarItem* item : m_items) { if (!item->is_visible()) @@ -895,13 +901,13 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 const Size cnv_size = parent.get_canvas_size(); const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); - const float icons_size = m_layout.icons_size * m_layout.scale; - const float separator_size = m_layout.separator_size * m_layout.scale; - const float gap_size = m_layout.gap_size * m_layout.scale; - const float border = m_layout.border * m_layout.scale; + const float icons_size = m_layout.icons_size; + const float separator_size = m_layout.separator_size; + const float gap_size = m_layout.gap_size; + const float border = m_layout.border; - float left = m_layout.left + border; - const float top = m_layout.top - border; + float left = m_layout.left + border + gap_size; + const float top = m_layout.top - border - gap_size; for (size_t id = 0; id < m_items.size(); ++id) { GLToolbarItem* item = m_items[id]; @@ -957,7 +963,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 return -2; } - left = right; + left = right + gap_size; } } @@ -969,10 +975,10 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& const Size cnv_size = parent.get_canvas_size(); const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); - const float icons_size = m_layout.icons_size * m_layout.scale; - const float separator_size = m_layout.separator_size * m_layout.scale; - const float gap_size = m_layout.gap_size * m_layout.scale; - const float border = m_layout.border * m_layout.scale; + const float icons_size = m_layout.icons_size; + const float separator_size = m_layout.separator_size; + const float gap_size = m_layout.gap_size; + const float border = m_layout.border; const float left = m_layout.left + border; float top = m_layout.top - border; @@ -1131,12 +1137,12 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte const float inv_cnv_w = 1.0f / cnv_w; const float inv_cnv_h = 1.0f / cnv_h; - const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; - const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; - const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w; - const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w; - const float border_x = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; - const float border_y = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + const float icons_size_x = 2.0f * m_layout.icons_size * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * inv_cnv_w; + const float gap_size = 2.0f * m_layout.gap_size * inv_cnv_w; + const float border_x = 2.0f * m_layout.border * inv_cnv_w; + const float border_y = 2.0f * m_layout.border * inv_cnv_h; const float separator_stride = separator_size + gap_size; const float icon_stride = icons_size_x + gap_size; @@ -1169,8 +1175,8 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte const float arr_tex_width = (float)m_arrow_texture.get_width(); const float arr_tex_height = (float)m_arrow_texture.get_height(); if (tex_id != 0 && arr_tex_width > 0.0f && arr_tex_height > 0.0f) { - const float arrow_size_x = 2.0f * m_layout.scale * arr_tex_width * inv_cnv_w; - const float arrow_size_y = 2.0f * m_layout.scale * arr_tex_height * inv_cnv_h; + const float arrow_size_x = 2.0f * arr_tex_width * inv_cnv_w; + const float arrow_size_y = 2.0f * arr_tex_height * inv_cnv_h; const float left_uv = 0.0f; const float right_uv = 1.0f; @@ -1203,17 +1209,18 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const float inv_cnv_w = 1.0f / cnv_w; const float inv_cnv_h = 1.0f / cnv_h; - const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; - const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; - const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w; - const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w; - const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; - const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + const float icons_size_x = 2.0f * m_layout.icons_size * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * inv_cnv_w; + const float gap_size_x = 2.0f * m_layout.gap_size * inv_cnv_w; + const float gap_size_y = 2.0f * m_layout.gap_size * inv_cnv_h; + const float border_w = 2.0f * m_layout.border * inv_cnv_w; + const float border_h = 2.0f * m_layout.border * inv_cnv_h; const float width = 2.0f * get_width() * inv_cnv_w; const float height = 2.0f * get_height() * inv_cnv_h; - const float separator_stride = separator_size + gap_size; - const float icon_stride = icons_size_x + gap_size; + const float separator_stride = separator_size + gap_size_x; + const float icon_stride = icons_size_x + 2 * gap_size_x; float left = 2.0f * m_layout.left * inv_cnv_w; float top = 2.0f * m_layout.top * inv_cnv_h; @@ -1222,18 +1229,30 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) render_background(left, top, right, bottom, border_w, border_h); - left += border_w; - top -= border_h; + const float margin_w = border_w + gap_size_x; + const float margin_h = border_h + gap_size_y; + left += margin_w; + top -= margin_h; + // renders icons + int id = 0; for (const GLToolbarItem* item : m_items) { + id++; if (!item->is_visible()) continue; if (item->is_separator()) left += separator_stride; else { - item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + if (item->is_pressed()) + render_background(left - (id == m_items.size() ? border_w : margin_w), + top + margin_h, + left + icons_size_x + (id == 1 ? border_w : margin_w), + top - icons_size_y - margin_h, + border_w, border_h); + + item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size)); left += icon_stride; } } @@ -1258,17 +1277,18 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const float inv_cnv_w = 1.0f / cnv_w; const float inv_cnv_h = 1.0f / cnv_h; - const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; - const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; - const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_h; - const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_h; - const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; - const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + const float icons_size_x = 2.0f * m_layout.icons_size * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * inv_cnv_h; + const float gap_size_x = 2.0f * m_layout.gap_size * inv_cnv_w; + const float gap_size_y = 2.0f * m_layout.gap_size * inv_cnv_h; + const float border_w = 2.0f * m_layout.border * inv_cnv_w; + const float border_h = 2.0f * m_layout.border * inv_cnv_h; const float width = 2.0f * get_width() * inv_cnv_w; const float height = 2.0f * get_height() * inv_cnv_h; - const float separator_stride = separator_size + gap_size; - const float icon_stride = icons_size_y + gap_size; + const float separator_stride = separator_size + gap_size_y; + const float icon_stride = icons_size_y + 2 * gap_size_y; float left = 2.0f * m_layout.left * inv_cnv_w; float top = 2.0f * m_layout.top * inv_cnv_h; @@ -1277,8 +1297,8 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) render_background(left, top, right, bottom, border_w, border_h); - left += border_w; - top -= border_h; + left += border_w + gap_size_x; + top -= border_h + gap_size_y; // renders icons for (const GLToolbarItem* item : m_items) { @@ -1288,7 +1308,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) if (item->is_separator()) top -= separator_stride; else { - item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size)); top -= icon_stride; } } @@ -1326,7 +1346,7 @@ bool GLToolbar::generate_icons_texture() states.push_back({ 1, false }); // HighlightedHidden } - unsigned int sprite_size_px = (unsigned int)(m_layout.icons_size * m_layout.scale); + unsigned int sprite_size_px = (unsigned int)(m_layout.icons_size); // // force even size // if (sprite_size_px % 2 != 0) // sprite_size_px += 1; diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 3f5c7be06b..ceb9f50580 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -294,6 +294,8 @@ public: void set_icons_size(float size); void set_scale(float scale); + float get_scale() const { return m_layout.scale; } + bool is_enabled() const { return m_enabled; } void set_enabled(bool enable) { m_enabled = enable; } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 53d8e1e933..dc99fb1741 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1874,20 +1874,12 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const if (is_limited && int_val < 50) int_val = 50; - return 0.01f * int_val * icon_sc; + return 0.01f * int_val; } void GUI_App::set_auto_toolbar_icon_scale(float scale) const { -#ifdef __APPLE__ - const float icon_sc = 1.0f; // for Retina display will be used its own scale -#else - const float icon_sc = m_em_unit * 0.1f; -#endif // __APPLE__ - - long int_val = std::min(int(std::lround(scale / icon_sc * 100)), 100); - std::string val = std::to_string(int_val); - + std::string val = std::to_string(int(std::lround(scale * 100))); app_config->set("auto_toolbar_size", val); } diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index acdd55acfe..34cfead654 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1478,14 +1478,18 @@ static void update_menu_item_def_colors(T* item) void MenuFactory::sys_color_changed() { - for (MenuWithSeparators* menu : { &m_object_menu, &m_sla_object_menu, &m_part_menu, &m_default_menu }) { - sys_color_changed_menu(dynamic_cast(menu));// msw_rescale_menu updates just icons, so use it + for (MenuWithSeparators* menu : { &m_object_menu, &m_sla_object_menu, &m_part_menu, &m_default_menu }) + sys_color_changed(dynamic_cast(menu)); +} + +void MenuFactory::sys_color_changed(wxMenu* menu) +{ + sys_color_changed_menu(menu);// msw_rescale_menu updates just icons, so use it #ifdef _WIN32 - // but under MSW we have to update item's bachground color - for (wxMenuItem* item : menu->GetMenuItems()) - update_menu_item_def_colors(item); + // but under MSW we have to update item's bachground color + for (wxMenuItem* item : menu->GetMenuItems()) + update_menu_item_def_colors(item); #endif - } } void MenuFactory::sys_color_changed(wxMenuBar* menubar) diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index 86dfcb4628..dffcb202f2 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -77,6 +77,7 @@ public: void update_default_menu(); void sys_color_changed(); + static void sys_color_changed(wxMenu* menu); static void sys_color_changed(wxMenuBar* menu_bar); wxMenu* default_menu(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 99caa946c8..8fea76a79c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -39,7 +39,7 @@ namespace Slic3r { namespace GUI { -const float GLGizmosManager::Default_Icons_Size = 64; +const float GLGizmosManager::Default_Icons_Size = 52;// 64; GLGizmosManager::GLGizmosManager(GLCanvas3D& parent) : m_parent(parent) @@ -71,11 +71,12 @@ GLGizmosManager::EType GLGizmosManager::get_gizmo_from_mouse(const Vec2d &mouse_ float icons_size = m_layout.scaled_icons_size(); float border = m_layout.scaled_border(); float stride_y = m_layout.scaled_stride_y(); + float gap_x = m_layout.scaled_gap_x(); float top_y = 0.5f * (cnv_h - height) + border; // is mouse horizontally in the area? - if ((border <= (float) mouse_pos(0) && - ((float) mouse_pos(0) <= border + icons_size))) { + if (border <= (float) mouse_pos(0) && + (float) mouse_pos(0) <= (border+gap_x + icons_size)) { // which icon is it on? size_t from_top = (size_t) ((float) mouse_pos(1) - top_y) / stride_y; // is it really on the icon or already past the border? @@ -808,7 +809,9 @@ void GLGizmosManager::do_render_overlay() const render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h); - top_x += border_w; + const float margin_w = border_w + m_layout.scaled_gap_x() * inv_cnv_w; + + top_x += margin_w; top_y -= border_h; const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w; @@ -832,9 +835,13 @@ void GLGizmosManager::do_render_overlay() const float current_y = FLT_MAX; for (size_t idx : selectable_idxs) { GLGizmoBase* gizmo = m_gizmos[idx].get(); + + if (m_current == idx) + render_background(top_x - margin_w, top_y + border_h, top_x + icons_size_x + margin_w, top_y - icons_size_y - border_h, border_w, border_h); + const unsigned int sprite_id = gizmo->get_sprite_id(); // higlighted state needs to be decided first so its highlighting in every other state - const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable() ? 0 : 3))); + const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? /*2*/1 : ((m_hover == idx) ? 1 : (gizmo->is_activable() ? 0 : 3))); const float u_left = u_offset + icon_idx * du; const float u_right = u_left + du - u_offset; @@ -856,12 +863,12 @@ void GLGizmosManager::do_render_overlay() const float GLGizmosManager::get_scaled_total_height() const { - return m_layout.scale * (2.0f * m_layout.border + (float)get_selectable_idxs().size() * m_layout.stride_y() - m_layout.gap_y); + return 2.0f * m_layout.scaled_border() + (float)get_selectable_idxs().size() * m_layout.scaled_stride_y() - m_layout.scaled_gap_y(); } float GLGizmosManager::get_scaled_total_width() const { - return 2.0f * m_layout.scaled_border() + m_layout.scaled_icons_size(); + return 2.0f * m_layout.scaled_border() + m_layout.scaled_icons_size() + m_layout.scaled_gap_x(); } GLGizmoBase* GLGizmosManager::get_current() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index ce0e39884c..6e55ce72c2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -94,14 +94,16 @@ private: float scale{ 1.0f }; float icons_size{ Default_Icons_Size }; float border{ 5.0f }; - float gap_y{ 5.0f }; + float gap_x{ 15.0f }; + float gap_y{ 15.0f }; float stride_y() const { return icons_size + gap_y;} - float scaled_icons_size() const { return scale * icons_size; } - float scaled_border() const { return scale * border; } - float scaled_gap_y() const { return scale * gap_y; } - float scaled_stride_y() const { return scale * stride_y(); } + float scaled_icons_size() const { return int(scale * icons_size); } + float scaled_border() const { return int(scale * border); } + float scaled_gap_x() const { return int(scale * gap_x); } + float scaled_gap_y() const { return int(scale * gap_y); } + float scaled_stride_y() const { return scaled_icons_size() + scaled_gap_y(); } }; GLCanvas3D& m_parent; @@ -231,6 +233,8 @@ public: // To end highlight set gizmo = undefined void set_highlight(EType gizmo, bool highlight_shown) { m_highlight = std::pair(gizmo, highlight_shown); } bool get_highlight_state() const { return m_highlight.second; } + float get_scaled_total_height() const; + float get_scaled_total_width() const; private: bool gizmo_event(SLAGizmoEventType action, @@ -242,10 +246,6 @@ private: void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; void do_render_overlay() const; - - float get_scaled_total_height() const; - float get_scaled_total_width() const; - bool generate_icons_texture(); void update_hover_state(const EType &type); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 127a402d94..ef498f0b6d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -64,6 +64,7 @@ #include "NotificationManager.hpp" #include "Preferences.hpp" #include "WebViewDialog.hpp" +#include "UserAccount.hpp" #ifdef _WIN32 #include @@ -595,12 +596,36 @@ static wxString GetTooltipForSettingsButton(PrinterTechnology pt) return from_u8(tooltip); } +void MainFrame::set_callbacks_for_topbar_menus() +{ + m_bar_menus.set_workspaces_menu_callbacks( + []() -> int { return wxGetApp().get_mode(); }, + [](/*ConfigOptionMode*/int mode) -> void { wxGetApp().save_mode(mode); }, + [](/*ConfigOptionMode*/int mode) -> std::string { return wxGetApp().get_mode_btn_color(mode); } + ); + + m_bar_menus.set_account_menu_callbacks( + []() -> void { wxGetApp().plater()->toggle_remember_user_account_session(); }, + []() -> void { wxGetApp().plater()->act_with_user_account(); }, + []() -> TopBarMenus::UserAccountInfo { + if (auto user_account = wxGetApp().plater()->get_user_account()) + return { user_account->is_logged(), + user_account->get_remember_session(), + user_account->get_username(), + user_account->get_avatar_path(true) }; + return TopBarMenus::UserAccountInfo(); + } + ); +} + void MainFrame::init_tabpanel() { wxGetApp().update_ui_colours_from_appconfig(); + set_callbacks_for_topbar_menus(); + if (wxGetApp().is_editor()) { - m_tmp_top_bar = new TopBar(this, &m_bar_menus, false); + m_tmp_top_bar = new TopBar(this, &m_bar_menus, [this]() -> void { select_tab(); }); m_tmp_top_bar->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_tmp_top_bar->Hide(); } @@ -855,7 +880,8 @@ void MainFrame::set_printer_webview_credentials(const std::string& usr, const st void Slic3r::GUI::MainFrame::refresh_account_menu(bool avatar/* = false */) { // Update User name in TopBar - m_bar_menus.UpdateAccountMenu(m_plater->get_user_account()); + m_bar_menus.UpdateAccountMenu(); + m_tabpanel->GetTopBarItemsCtrl()->UpdateAccountButton(avatar); m_tmp_top_bar->GetTopBarItemsCtrl()->UpdateAccountButton(avatar); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 147059d945..be329355d5 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -171,6 +171,7 @@ public: void update_title(); + void set_callbacks_for_topbar_menus(); void init_tabpanel(); void create_preset_tabs(); void add_created_tab(Tab* panel, const std::string& bmp_name = ""); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7fe362f5ea..56b66db03b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -643,10 +643,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D = new View3D(q, bed, &model, config, &background_process); preview = new Preview(q, bed, &model, config, &background_process, &gcode_result, [this]() { schedule_background_process(); }); -#ifdef __APPLE__ // set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size); -#endif // __APPLE__ panels.push_back(view3D); panels.push_back(preview); @@ -1073,6 +1071,7 @@ void Plater::priv::collapse_sidebar(bool collapse) new_tooltip += " [Shift+Tab]"; int id = collapse_toolbar.get_item_id("collapse_sidebar"); collapse_toolbar.set_tooltip(id, new_tooltip); + collapse_toolbar.set_enabled(collapse || wxGetApp().app_config->get_bool("show_collapse_button")); notification_manager->set_sidebar_collapsed(collapse); } @@ -3273,8 +3272,8 @@ bool Plater::priv::init_view_toolbar() view_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Left); view_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Bottom); - view_toolbar.set_border(5.0f); - view_toolbar.set_gap_size(1.0f); + //view_toolbar.set_border(5.0f); + //view_toolbar.set_gap_size(1.0f); GLToolbarItem::Data item; @@ -3324,9 +3323,9 @@ bool Plater::priv::init_collapse_toolbar() collapse_toolbar.set_layout_type(GLToolbar::Layout::Vertical); collapse_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Right); collapse_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Top); - collapse_toolbar.set_border(5.0f); - collapse_toolbar.set_separator_size(5); - collapse_toolbar.set_gap_size(2); + //collapse_toolbar.set_border(5.0f); + //collapse_toolbar.set_separator_size(5); + //collapse_toolbar.set_gap_size(2); GLToolbarItem::Data item; @@ -6816,6 +6815,22 @@ const UserAccount* Plater::get_user_account() const return p->user_account.get(); } +void Plater::toggle_remember_user_account_session() +{ + if (p->user_account) + p->user_account->toggle_remember_session(); +} + +void Plater::act_with_user_account() +{ + if (p->user_account) { + if (p->user_account->is_logged()) + p->user_account->do_logout(); + else + p->user_account->do_login(); + } +} + void Plater::init_notification_manager() { p->init_notification_manager(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 28c33b13c3..d841d17378 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -358,6 +358,9 @@ public: UserAccount* get_user_account(); const UserAccount* get_user_account() const; + void toggle_remember_user_account_session(); + void act_with_user_account(); + void init_notification_manager(); void bring_instance_forward(); diff --git a/src/slic3r/GUI/Sidebar.cpp b/src/slic3r/GUI/Sidebar.cpp index 658881ad8e..334b04eff1 100644 --- a/src/slic3r/GUI/Sidebar.cpp +++ b/src/slic3r/GUI/Sidebar.cpp @@ -513,7 +513,11 @@ Sidebar::Sidebar(Plater *parent) auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_scrolled_panel, 1, wxEXPAND); - sizer->Add(btns_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, margin_5); + sizer->Add(btns_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM +#ifndef _WIN32 + | wxRIGHT +#endif // __linux__ + , margin_5); SetSizer(sizer); // Events diff --git a/src/slic3r/GUI/TopBar.cpp b/src/slic3r/GUI/TopBar.cpp index fdca313fdb..8665cd1cbc 100644 --- a/src/slic3r/GUI/TopBar.cpp +++ b/src/slic3r/GUI/TopBar.cpp @@ -2,10 +2,7 @@ #include "TopBarMenus.hpp" #include "GUI_App.hpp" -#include "MainFrame.hpp" -#include "Plater.hpp" #include "Search.hpp" -#include "UserAccount.hpp" #include "format.hpp" #include "I18N.hpp" @@ -166,8 +163,14 @@ void TopBarItemsCtrl::Button::sys_color_changed() m_foreground_color = wxGetApp().get_label_clr_default(); } +#ifdef __linux__ +const int icon_sz = 20; +#else +const int icon_sz = 24; +#endif + TopBarItemsCtrl::ButtonWithPopup::ButtonWithPopup(wxWindow* parent, const wxString& label, const std::string& icon_name, wxSize size) - :TopBarItemsCtrl::Button(parent, label, icon_name, 24, size) + :TopBarItemsCtrl::Button(parent, label, icon_name, icon_sz, size) { if (size != wxDefaultSize) m_fixed_width = size.x * 0.1; @@ -222,16 +225,13 @@ void TopBarItemsCtrl::ButtonWithPopup::SetLabel(const wxString& label) void TopBarItemsCtrl::UpdateAccountButton(bool avatar/* = false*/) { - auto user_account = wxGetApp().plater()->get_user_account(); - const wxString user_name = user_account->is_logged() ? from_u8(user_account->get_username()) : _L("Anonymous"); - m_account_btn->SetLabel(m_collapsed_btns ? "" : user_name); + TopBarMenus::UserAccountInfo user_account = m_menus->get_user_account_info(); + const wxString user_name = user_account.is_logged ? from_u8(user_account.user_name) : _L("Log in"); m_account_btn->SetToolTip(user_name); - const int icon_sz = 24; #ifdef __linux__ if (avatar) { - if (user_account->is_logged()) { - boost::filesystem::path path = user_account->get_avatar_path(true); - ScalableBitmap new_logo(this, path, wxSize(icon_sz, icon_sz)); + if (user_account.is_logged) { + ScalableBitmap new_logo(this, user_account.avatar_path, wxSize(icon_sz, icon_sz)); if (new_logo.IsOk()) m_account_btn->SetBitmap_(new_logo); else @@ -243,9 +243,8 @@ void TopBarItemsCtrl::UpdateAccountButton(bool avatar/* = false*/) } #else if (avatar) { - if (user_account->is_logged()) { - boost::filesystem::path path = user_account->get_avatar_path(true); - ScalableBitmap new_logo(this, path, wxSize(icon_sz, icon_sz)); + if (user_account.is_logged) { + ScalableBitmap new_logo(this, user_account.avatar_path, wxSize(icon_sz, icon_sz)); if (new_logo.IsOk()) m_account_btn->SetBitmapBundle(new_logo.bmp()); else @@ -256,7 +255,10 @@ void TopBarItemsCtrl::UpdateAccountButton(bool avatar/* = false*/) } } #endif - m_account_btn->Refresh(); + + m_account_btn->SetLabel(m_collapsed_btns ? "" : user_name); + this->Layout(); +// m_account_btn->Refresh(); } void TopBarItemsCtrl::UnselectPopupButtons() @@ -416,9 +418,10 @@ void TopBarItemsCtrl::update_btns_width() } } -TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullptr*/, bool is_main/* = true*/) : +TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullptr*/, std::function cb_settings_btn/* = nullptr*/) : wxControl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL) ,m_menus(menus) + ,m_cb_settings_btn(cb_settings_btn) { wxGetApp().UpdateDarkUI(this); @@ -447,11 +450,9 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullpt }); #endif - if (!is_main) { + if (m_cb_settings_btn) { m_settings_btn = new Button(this, _L("Settings"/*, "settings"*/)); - m_settings_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent& event) { - wxGetApp().mainframe->select_tab(); - }); + m_settings_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { m_cb_settings_btn(); }); left_sizer->Add(m_settings_btn, 0, wxALIGN_CENTER_VERTICAL); } @@ -459,7 +460,7 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullpt left_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, m_btn_margin); CreateSearch(); - if (!is_main) + if (m_cb_settings_btn) wxGetApp().searcher().set_search_input(m_search); wxBoxSizer* search_sizer = new wxBoxSizer(wxVERTICAL); @@ -479,7 +480,7 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullpt m_menus->Popup(this, &m_menus->workspaces, m_workspace_btn->get_popup_pos()); }); - m_account_btn = new ButtonWithPopup(this, _L("Anonymous"), "user", wxSize(180, -1)); + m_account_btn = new ButtonWithPopup(this, _L("Log in"), "user", wxSize(180, -1)); right_sizer->Add(m_account_btn, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxRIGHT, m_btn_margin); m_account_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { @@ -491,10 +492,10 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullpt m_sizer->SetItemMinSize(1, wxSize(42 * wxGetApp().em_unit(), -1)); - this->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) { - auto user_account = wxGetApp().plater()->get_user_account(); - evt.Enable(user_account ? user_account->is_logged() : false); - evt.Check (user_account ? user_account->get_remember_session() : false); + this->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { + auto user_account = m_menus->get_user_account_info(); + evt.Enable(user_account.is_logged); + evt.Check (user_account.remember_session); }, m_menus->remember_me_item_id); update_btns_width(); @@ -502,9 +503,7 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullpt void TopBarItemsCtrl::UpdateMode() { - auto mode = wxGetApp().get_mode(); - - wxBitmapBundle bmp = *get_bmp_bundle("mode", 16, -1, wxGetApp().get_mode_btn_color(mode)); + wxBitmapBundle bmp = *m_menus->get_workspace_bitmap(); #ifdef __linux__ m_workspace_btn->SetBitmap(bmp); m_workspace_btn->SetBitmapCurrent(bmp); @@ -513,7 +512,7 @@ void TopBarItemsCtrl::UpdateMode() m_workspace_btn->SetBitmapBundle(bmp); #endif - m_workspace_btn->SetLabel(m_collapsed_btns ? "" : m_menus->get_workspace_name(mode)); + m_workspace_btn->SetLabel(m_collapsed_btns ? "" : m_menus->get_workspace_name()); this->Layout(); } @@ -541,6 +540,10 @@ void TopBarItemsCtrl::Rescale() void TopBarItemsCtrl::OnColorsChanged() { wxGetApp().UpdateDarkUI(this); + + if (m_menus) + m_menus->sys_color_changed(); + if (m_menu_btn) m_menu_btn->sys_color_changed(); if (m_settings_btn) @@ -548,6 +551,8 @@ void TopBarItemsCtrl::OnColorsChanged() m_workspace_btn->sys_color_changed(); m_account_btn->sys_color_changed(); + UpdateAccountButton(true); + m_search->SysColorsChanged(); UpdateSelection(); @@ -640,10 +645,6 @@ void TopBarItemsCtrl::ShowFull() if (m_settings_btn) m_settings_btn->Show(); m_account_btn->Show(); - m_menus->set_cb_on_user_item([this]() { - m_account_btn->set_selected(true); - m_menus->Popup(this, &m_menus->account, m_account_btn->get_popup_pos()); - }); update_btns_width(); UpdateSearchSizeAndPosition(); } @@ -655,7 +656,6 @@ void TopBarItemsCtrl::ShowJustMode() if (m_settings_btn) m_settings_btn->Hide(); m_account_btn->Hide(); - m_menus->set_cb_on_user_item(nullptr); update_btns_width(); UpdateSearchSizeAndPosition(); } diff --git a/src/slic3r/GUI/TopBar.hpp b/src/slic3r/GUI/TopBar.hpp index ac9fe018d5..0225e3f3d6 100644 --- a/src/slic3r/GUI/TopBar.hpp +++ b/src/slic3r/GUI/TopBar.hpp @@ -57,19 +57,21 @@ class TopBarItemsCtrl : public wxControl wxPoint get_popup_pos(); }; - TopBarMenus* m_menus{ nullptr }; + TopBarMenus* m_menus { nullptr }; - ::TextInput* m_search{ nullptr }; + ::TextInput* m_search { nullptr }; - int m_btns_width{ 0 }; - bool m_collapsed_btns{ false }; + int m_btns_width { 0 }; + bool m_collapsed_btns { false }; + + std::function m_cb_settings_btn { nullptr }; void update_btns_width(); public: TopBarItemsCtrl(wxWindow* parent, TopBarMenus* menus = nullptr, - bool is_main = true); + std::function cb_settings_btn = nullptr); ~TopBarItemsCtrl() {} void SetSelection(int sel, bool force = false); @@ -124,12 +126,12 @@ public: TopBar( wxWindow * parent, TopBarMenus* menus, - bool is_main = true) + std::function cb_settings_btn = nullptr) { Init(); // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10 // with multiple high resolution displays connected. - Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME, menus, is_main); + Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME, menus, cb_settings_btn); } bool Create(wxWindow * parent, @@ -138,12 +140,12 @@ public: const wxSize & size = wxDefaultSize, long style = 0, TopBarMenus* menus = nullptr, - bool is_main = true) + std::function cb_settings_btn = nullptr) { if (!wxBookCtrlBase::Create(parent, winid, pos, size, style | wxBK_TOP)) return false; - m_bookctrl = new TopBarItemsCtrl(this, menus, is_main); + m_bookctrl = new TopBarItemsCtrl(this, menus, cb_settings_btn); wxSizer* mainSizer = new wxBoxSizer(IsVertical() ? wxVERTICAL : wxHORIZONTAL); diff --git a/src/slic3r/GUI/TopBarMenus.cpp b/src/slic3r/GUI/TopBarMenus.cpp index b3c28309cb..e7253e4561 100644 --- a/src/slic3r/GUI/TopBarMenus.cpp +++ b/src/slic3r/GUI/TopBarMenus.cpp @@ -1,10 +1,8 @@ #include "TopBarMenus.hpp" #include "TopBar.hpp" -#include "GUI_App.hpp" -#include "Plater.hpp" -#include "UserAccount.hpp" - +#include "libslic3r/Config.hpp" //ConfigOptionMode +#include "GUI_Factories.hpp" #include "I18N.hpp" using namespace Slic3r::GUI; @@ -12,7 +10,6 @@ using namespace Slic3r::GUI; TopBarMenus::TopBarMenus() { CreateAccountMenu(); - ApplyWorkspacesMenu(); UpdateAccountMenu(); BindEvtClose(); @@ -28,12 +25,38 @@ void TopBarMenus::AppendMenuSeparaorItem() main.AppendSeparator(); } -wxString TopBarMenus::get_workspace_name(const int mode) +wxString TopBarMenus::get_workspace_name(int mode/* = -1*/) { + if (mode < 0 && m_cb_get_mode) + mode = m_cb_get_mode(); + return mode == Slic3r::ConfigOptionMode::comSimple ? _L("Beginner mode") : mode == Slic3r::ConfigOptionMode::comAdvanced ? _L("Normal mode") : _L("Expert mode"); } +wxBitmapBundle* TopBarMenus::get_workspace_bitmap(int mode/* = -1*/) +{ + assert(m_cb_get_mode_btn_color); + if (mode < 0 && m_cb_get_mode) + mode = m_cb_get_mode(); + + return get_bmp_bundle("mode", 16, -1, m_cb_get_mode_btn_color(mode)); +} + +TopBarMenus::UserAccountInfo TopBarMenus::get_user_account_info() +{ + if (m_cb_get_user_account_info) + return m_cb_get_user_account_info(); + return UserAccountInfo(); +} + +void TopBarMenus::sys_color_changed() +{ + MenuFactory::sys_color_changed(&main); + MenuFactory::sys_color_changed(&workspaces); + MenuFactory::sys_color_changed(&account); +} + void TopBarMenus::ApplyWorkspacesMenu() { wxMenuItemList& items = workspaces.GetMenuItems(); @@ -47,10 +70,11 @@ void TopBarMenus::ApplyWorkspacesMenu() Slic3r::ConfigOptionMode::comExpert }) { const wxString label = get_workspace_name(mode); append_menu_item(&workspaces, wxID_ANY, label, label, - [mode](wxCommandEvent&) { - if (wxGetApp().get_mode() != mode) - wxGetApp().save_mode(mode); - }, get_bmp_bundle("mode", 16, -1, wxGetApp().get_mode_btn_color(mode))); + [mode, this](wxCommandEvent&) { + if (m_cb_get_mode && m_cb_save_mode && + m_cb_get_mode() != mode) + m_cb_save_mode(mode); + }, get_workspace_bitmap(mode)); if (mode < Slic3r::ConfigOptionMode::comExpert) workspaces.AppendSeparator(); @@ -61,24 +85,20 @@ void TopBarMenus::CreateAccountMenu() { remember_me_item_id = wxWindow::NewControlId(); append_menu_check_item(&account, remember_me_item_id, _L("Remember me"), "" , - [](wxCommandEvent&) { wxGetApp().plater()->get_user_account()->toggle_remember_session(); } , nullptr); + [this](wxCommandEvent&) { if (m_cb_toggle_remember_session) m_cb_toggle_remember_session(); }, nullptr); m_login_item = append_menu_item(&account, wxID_ANY, "", "", - [](wxCommandEvent&) { - auto user_account = wxGetApp().plater()->get_user_account(); - if (user_account->is_logged()) - user_account->do_logout(); - else - user_account->do_login(); - }, get_bmp_bundle("login", 16)); + [this](wxCommandEvent&) { if (m_cb_act_with_user_account) m_cb_act_with_user_account(); }, "login"); } -void TopBarMenus::UpdateAccountMenu(Slic3r::GUI::UserAccount* user_account) +void TopBarMenus::UpdateAccountMenu() { - bool is_logged = user_account && user_account->is_logged(); + bool is_logged{ false }; + if (m_cb_get_user_account_info) + is_logged = m_cb_get_user_account_info().is_logged; if (m_login_item) { m_login_item->SetItemLabel(is_logged ? _L("Prusa Account Log out") : _L("Prusa Account Log in")); - m_login_item->SetBitmap(is_logged ? *get_bmp_bundle("logout", 16) : *get_bmp_bundle("login", 16)); + set_menu_item_bitmap(m_login_item, is_logged ? "logout" : "login"); } } diff --git a/src/slic3r/GUI/TopBarMenus.hpp b/src/slic3r/GUI/TopBarMenus.hpp index a86f09a051..20235cba2e 100644 --- a/src/slic3r/GUI/TopBarMenus.hpp +++ b/src/slic3r/GUI/TopBarMenus.hpp @@ -6,20 +6,30 @@ class TopBarItemsCtrl; class wxString; -namespace Slic3r { -namespace GUI { -class UserAccount; -} -} - class TopBarMenus { +public: + struct UserAccountInfo { + bool is_logged { false }; + bool remember_session{ false }; + std::string user_name; + boost::filesystem::path avatar_path; + }; + +private: + // Prusa Account menu items wxMenuItem* m_login_item { nullptr }; TopBarItemsCtrl* m_popup_ctrl { nullptr }; - std::function m_cb_on_user_item { nullptr }; + std::function m_cb_get_mode { nullptr }; + std::function m_cb_save_mode { nullptr }; + std::function m_cb_get_mode_btn_color { nullptr }; + + std::function m_cb_toggle_remember_session { nullptr }; + std::function m_cb_act_with_user_account { nullptr }; + std::functionm_cb_get_user_account_info { nullptr }; public: wxMenu main; @@ -34,13 +44,37 @@ public: void AppendMenuSeparaorItem(); void ApplyWorkspacesMenu(); void CreateAccountMenu(); - void UpdateAccountMenu(Slic3r::GUI::UserAccount* user_account = nullptr); + void UpdateAccountMenu(); void Popup(TopBarItemsCtrl* popup_ctrl, wxMenu* menu, wxPoint pos); void BindEvtClose(); - wxString get_workspace_name(const /*ConfigOptionMode*/int mode); - void set_cb_on_user_item (std::function cb) { m_cb_on_user_item = cb; } + void sys_color_changed(); + + wxString get_workspace_name(/*ConfigOptionMode*/int mode = -1); + wxBitmapBundle* get_workspace_bitmap(/*ConfigOptionMode*/int mode = -1); + + UserAccountInfo get_user_account_info(); + + void set_workspaces_menu_callbacks(std::function cb_get_mode, + std::function cb_save_mode, + std::function cb_get_mode_btn_color) + { + m_cb_get_mode = cb_get_mode; + m_cb_save_mode = cb_save_mode; + m_cb_get_mode_btn_color = cb_get_mode_btn_color; + + ApplyWorkspacesMenu(); + } + + void set_account_menu_callbacks(std::function cb_toggle_remember_session, + std::function cb_act_with_user_account , + std::function cb_get_user_account_info ) + { + m_cb_toggle_remember_session = cb_toggle_remember_session; + m_cb_act_with_user_account = cb_act_with_user_account; + m_cb_get_user_account_info = cb_get_user_account_info; + } }; diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index b8ca306db8..6752991cb3 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -249,9 +249,9 @@ void TextInput::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (align_right) textPos.x += labelSize.x; if (text_ctrl) { - wxSize textSize = text_ctrl->GetSize(); + wxSize textSize = text_ctrl->GetBestSize(); wxClientDC dc(this); - const int r_shift = int((dd_icon_size.x == 0 ? 3. : 2.) * dc.GetContentScaleFactor()); + const int r_shift = int(dd_icon_size.x == 0 ? (3. * dc.GetContentScaleFactor()) : ((size.y - dd_icon_size.y) / 2)); textSize.x = size.x - textPos.x - labelSize.x - dd_icon_size.x - r_shift; text_ctrl->SetSize(textSize); text_ctrl->SetPosition({textPos.x, (size.y - textSize.y) / 2}); @@ -283,7 +283,7 @@ void TextInput::render(wxDC& dc) wxSize size = GetSize(); bool align_right = GetWindowStyle() & wxRIGHT; // start draw - wxPoint pt = {5, 0}; + wxPoint pt = { 5 + text_ctrl->GetMargins().x, 0}; if (icon.IsOk()) { wxSize szIcon = get_preferred_size(icon, m_parent); pt.y = (size.y - szIcon.y) / 2; @@ -299,14 +299,15 @@ void TextInput::render(wxDC& dc) wxPoint pt_r = {size.x, 0}; if (drop_down_icon.bmp().IsOk()) { wxSize szIcon = drop_down_icon.GetSize(); - pt_r.x -= szIcon.x + 2; pt_r.y = (size.y - szIcon.y) / 2; + pt_r.x -= szIcon.x + pt_r.y; dd_icon_rect = wxRect(pt_r, szIcon); dc.DrawBitmap(drop_down_icon.get_bitmap(), pt_r); + pt_r.x -= 5; } auto text = wxWindow::GetLabel(); - if (!text.IsEmpty()) { + if (!text_ctrl->IsShown() && !text.IsEmpty()) { wxSize textSize = text_ctrl->GetSize(); if (align_right) { pt.x += textSize.x; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 5ab0bfca03..4ecf3d93cf 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -215,6 +215,16 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, return item; } +void set_menu_item_bitmap(wxMenuItem* item, const std::string& icon_name) +{ + item->SetBitmap(*get_bmp_bundle(icon_name)); +#ifndef __linux__ + const auto it = msw_menuitem_bitmaps.find(item->GetId()); + if (it != msw_menuitem_bitmaps.end() && it->second != icon_name) + it->second = icon_name; +#endif // !__linux__ +} + /* Function for rescale of buttons in Dialog under MSW if dpi is changed. * btn_ids - vector of buttons identifiers */ @@ -475,6 +485,18 @@ ScalableBitmap::ScalableBitmap(wxWindow* parent, boost::filesystem::path& icon_p if (ext == ".png" || ext == ".jpg") { bitmap.LoadFile(path, ext == ".png" ? wxBITMAP_TYPE_PNG : wxBITMAP_TYPE_JPEG); + // check if the bitmap has a square shape + + if (wxSize sz = bitmap.GetSize(); sz.x != sz.y) { + const int bmp_side = std::min(sz.GetWidth(), sz.GetHeight()); + + wxRect rc = sz.GetWidth() > sz.GetHeight() ? + wxRect(int( 0.5 * (sz.x - sz.y)), 0, bmp_side, bmp_side) : + wxRect(0, int( 0.5 * (sz.y - sz.x)), bmp_side, bmp_side) ; + + bitmap = bitmap.GetSubBitmap(rc); + } + // set mask for circle shape wxBitmapBundle mask_bmps = *get_bmp_bundle("user_mask", bitmap.GetSize().GetWidth()); @@ -566,10 +588,15 @@ ScalableButton::ScalableButton( wxWindow * parent, SetBitmap(bitmap.bmp()); } -void ScalableButton::SetBitmap_(const ScalableBitmap& bmp) +void ScalableButton::SetBitmap_(const ScalableBitmap& bitmap) { - SetBitmap(bmp.bmp()); - m_current_icon_name = bmp.name(); + const wxBitmapBundle& bmp = bitmap.bmp(); + SetBitmap(bmp); + SetBitmapCurrent(bmp); + SetBitmapPressed(bmp); + SetBitmapFocus(bmp); + SetBitmapDisabled(bmp); + m_current_icon_name = bitmap.name(); } bool ScalableButton::SetBitmap_(const std::string& bmp_name) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index d64e7abdf1..fc96f48cbd 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -53,6 +53,8 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, void enable_menu_item(wxUpdateUIEvent& evt, std::function const cb_condition, wxMenuItem* item, wxWindow* win); +void set_menu_item_bitmap(wxMenuItem* item, const std::string& icon_name); + class wxDialog; void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector& btn_ids, double height_koef = 1.);