Merge branch 'ys_spe2327'

This commit is contained in:
Lukas Matena 2024-06-12 14:39:38 +02:00
commit f889bf470c
22 changed files with 422 additions and 252 deletions

View File

@ -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">

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 500 B

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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; }

View File

@ -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);
}

View File

@ -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<wxMenu*>(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<wxMenu*>(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)

View File

@ -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();

View File

@ -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

View File

@ -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<EType, bool>(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);

View File

@ -64,6 +64,7 @@
#include "NotificationManager.hpp"
#include "Preferences.hpp"
#include "WebViewDialog.hpp"
#include "UserAccount.hpp"
#ifdef _WIN32
#include <dbt.h>
@ -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);
}

View File

@ -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 = "");

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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<void()> 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();
}

View File

@ -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<void()> m_cb_settings_btn { nullptr };
void update_btns_width();
public:
TopBarItemsCtrl(wxWindow* parent,
TopBarMenus* menus = nullptr,
bool is_main = true);
std::function<void()> 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<void()> 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<void()> 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);

View File

@ -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");
}
}

View File

@ -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<void()> m_cb_on_user_item { nullptr };
std::function<int()> m_cb_get_mode { nullptr };
std::function<void(int)> m_cb_save_mode { nullptr };
std::function<std::string(int)> m_cb_get_mode_btn_color { nullptr };
std::function<void()> m_cb_toggle_remember_session { nullptr };
std::function<void()> m_cb_act_with_user_account { nullptr };
std::function<UserAccountInfo()>m_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<void()> 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</*ConfigOptionMode*/int()> cb_get_mode,
std::function<void(/*ConfigOptionMode*/int)> cb_save_mode,
std::function<std::string(/*ConfigOptionMode*/int)> 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<void()> cb_toggle_remember_session,
std::function<void()> cb_act_with_user_account ,
std::function<UserAccountInfo()> 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;
}
};

View File

@ -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;

View File

@ -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)

View File

@ -53,6 +53,8 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string,
void enable_menu_item(wxUpdateUIEvent& evt, std::function<bool()> 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<int>& btn_ids, double height_koef = 1.);