From c5f92578787a96b7a9c8b89f2d5100f2cc3b860c Mon Sep 17 00:00:00 2001 From: yw4z Date: Fri, 18 Sep 2026 18:43:42 +0300 Subject: [PATCH] Compact bbl nozzle UI (#15083) * init * drop usage of StaticGroup for ExtruderGroup * completely remove StaticGroup from project * fix alignment of "Not installed" text * fix crash on linux while clicking edit button * Fix background color on macOS --------- Co-authored-by: Noisyfox --- resources/images/edit_12px.svg | 1 + src/slic3r/CMakeLists.txt | 2 - src/slic3r/GUI/Plater.cpp | 195 +++++++++++---------- src/slic3r/GUI/Widgets/MultiNozzleSync.cpp | 46 +++-- src/slic3r/GUI/Widgets/MultiNozzleSync.hpp | 6 +- src/slic3r/GUI/Widgets/StaticBox.cpp | 12 +- src/slic3r/GUI/Widgets/StaticBox.hpp | 3 + src/slic3r/GUI/Widgets/StaticGroup.cpp | 28 --- src/slic3r/GUI/Widgets/StaticGroup.hpp | 19 -- 9 files changed, 157 insertions(+), 155 deletions(-) create mode 100644 resources/images/edit_12px.svg delete mode 100644 src/slic3r/GUI/Widgets/StaticGroup.cpp delete mode 100644 src/slic3r/GUI/Widgets/StaticGroup.hpp diff --git a/resources/images/edit_12px.svg b/resources/images/edit_12px.svg new file mode 100644 index 0000000000..b77ddc2b4e --- /dev/null +++ b/resources/images/edit_12px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 36274669b0..18730b248b 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -14,8 +14,6 @@ set(SLIC3R_GUI_SOURCES GUI/2DBed.hpp GUI/3DBed.cpp GUI/3DBed.hpp - GUI/Widgets/StaticGroup.cpp - GUI/Widgets/StaticGroup.hpp GUI/3DScene.cpp GUI/3DScene.hpp GUI/Widgets/FilamentLoad.cpp diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1cdf7204df..502265af00 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -148,7 +148,6 @@ #include "Widgets/RadioGroup.hpp" #include "Widgets/CheckBox.hpp" #include "Widgets/Button.hpp" -#include "Widgets/StaticGroup.hpp" #include "GUI_ObjectTable.hpp" #include "libslic3r/Thread.hpp" @@ -475,14 +474,9 @@ enum class ActionButtonType : int { abSendGCode }; -// Background for the extruder-group title chip and its edit buttons, matching the StaticGroup -// interior. macOS keeps a lighter #F7F7F7 tint in light mode; dark mode uses the mapped colour. +// Background for the extruder-group title chip and its edit buttons static wxColour extruder_group_chip_bg() { -#ifdef __WXOSX__ - if (!wxGetApp().dark_mode()) - return wxColour("#F7F7F7"); -#endif return StateColor::darkModeColorFor(*wxWHITE); } @@ -497,38 +491,39 @@ public: SetBackgroundColour(extruder_group_chip_bg()); auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto label_color = StateColor::darkModeColorFor(wxColour("#363636")); + m_label = new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - m_label->SetFont(Label::Body_13); - m_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B"))); + m_label->SetFont(Label::Body_12); + m_label->SetForegroundColour(label_color); m_brace_left = new wxStaticText(this, wxID_ANY, "(", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - m_brace_left->SetFont(Label::Body_13); - m_brace_left->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_brace_left->SetFont(Label::Body_12); + m_brace_left->SetForegroundColour(label_color); m_brace_left->Hide(); m_count = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - m_count->SetFont(Label::Body_13.Bold()); - m_count->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_count->SetFont(Label::Body_12.Bold()); + m_count->SetForegroundColour(label_color); m_count->Hide(); m_brace_right = new wxStaticText(this, wxID_ANY, ")", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - m_brace_right->SetFont(Label::Body_13); - m_brace_right->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_brace_right->SetFont(Label::Body_12); + m_brace_right->SetForegroundColour(label_color); m_brace_right->Hide(); - m_hover_btn = new ScalableButton(this, wxID_ANY, "dot"); - m_hover_btn->SetMinSize(wxSize(FromDIP(25), -1)); + m_hover_btn = new ScalableButton(this, wxID_ANY, "edit_12px", wxEmptyString, FromDIP(wxSize(12,12)), wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 12); m_hover_btn->SetBackgroundColour(extruder_group_chip_bg()); m_hover_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) { if (m_enabled && m_hover_on_click) m_hover_on_click(); }); - sizer->Add(m_label, 0, wxALIGN_CENTER_VERTICAL); - sizer->Add(m_brace_left, 0, wxALIGN_CENTER_VERTICAL); - sizer->Add(m_count, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_label , 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, FromDIP(4)); + sizer->Add(m_brace_left , 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_count , 0, wxALIGN_CENTER_VERTICAL); sizer->Add(m_brace_right, 0, wxALIGN_CENTER_VERTICAL); - sizer->Add(m_hover_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + sizer->Add(m_hover_btn , 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, FromDIP(4)); // No SetSizerAndFit: that would record the count-hidden width as an explicit min size, // which outranks best size in sizer allocation, so once the count is shown any ancestor @@ -540,7 +535,7 @@ public: void EnableEdit(bool enable) { m_enabled = enable; - m_hover_btn->SetBitmap_(enable ? "edit" : "dot"); + //m_hover_btn->SetBitmap_(enable ? "edit_12px" : "dot"); // it causes crash if icon sizes not matches } void SetOnHoverClick(std::function on_click) { m_hover_on_click = std::move(on_click); } @@ -551,11 +546,13 @@ public: m_count->Hide(); m_brace_left->Hide(); m_brace_right->Hide(); + m_hover_btn->Hide(); } else { m_count->SetLabel(wxString::Format("%d", count)); m_count->Show(); m_brace_left->Show(); m_brace_right->Show(); + m_hover_btn->Show(); } UpdateSizing(); } @@ -566,15 +563,19 @@ public: UpdateSizing(); } - void Rescale() { m_hover_btn->msw_rescale(); } + void Rescale() { + m_hover_btn->msw_rescale(); + UpdateSizing(); + } // Re-apply the chip colours on a live light/dark switch (they are set once at construction). void sys_color_changed() { SetBackgroundColour(extruder_group_chip_bg()); - m_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B"))); + auto label_color = StateColor::darkModeColorFor(wxColour("#363636")); + m_label->SetForegroundColour(label_color); for (wxStaticText *t : {m_brace_left, m_count, m_brace_right}) - t->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + t->SetForegroundColour(label_color); m_hover_btn->SetBackgroundColour(extruder_group_chip_bg()); Refresh(); } @@ -601,11 +602,12 @@ private: bool m_enabled{false}; }; -struct ExtruderGroup : StaticGroup +struct ExtruderGroup : StaticBox { ExtruderGroup(wxWindow * parent, int index, wxString const &title); - wxStaticBoxSizer *sizer = nullptr; + wxBoxSizer * sizer = nullptr; HoverLabel * hover_label = nullptr; + wxStaticText* ams_label{nullptr}; ScalableButton * btn_edit = nullptr; ComboBox * combo_diameter = nullptr; ComboBox * combo_flow = nullptr; @@ -645,8 +647,10 @@ struct ExtruderGroup : StaticGroup { if (hover_label) hover_label->Rescale(); - if (btn_edit) + if (btn_edit){ btn_edit->msw_rescale(); + btn_edit->SetMinSize(ams_label->GetSize()); + } btn_up->msw_rescale(); btn_down->msw_rescale(); combo_diameter->Rescale(); @@ -861,9 +865,9 @@ void Sidebar::priv::layout_printer(bool isBBL, bool isDual) // double extruder_dual_sizer = new wxBoxSizer(wxHORIZONTAL); - extruder_dual_sizer->Add(left_extruder->sizer, 1, wxEXPAND, 0); + extruder_dual_sizer->Add(left_extruder, 1, wxEXPAND, 0); extruder_dual_sizer->AddSpacer(FromDIP(4)); - extruder_dual_sizer->Add(right_extruder->sizer, 1, wxEXPAND, 0); + extruder_dual_sizer->Add(right_extruder, 1, wxEXPAND, 0); // Filament Track Switch status icon, floated over the extruder AMS area (positioned in // update_extruder_separator_icon). Created hidden; a click re-shows the ready/not-ready tip. @@ -878,7 +882,9 @@ void Sidebar::priv::layout_printer(bool isBBL, bool isDual) } // single - extruder_single_sizer = single_extruder->sizer; + extruder_single_sizer = new wxBoxSizer(wxHORIZONTAL); + extruder_single_sizer->Add(single_extruder, 1, wxEXPAND, 0); + wxBoxSizer * extruder_sizer = new wxBoxSizer(wxVERTICAL); extruder_sizer->Add(extruder_dual_sizer , 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(SidebarProps::ContentMargin())); extruder_sizer->Add(extruder_single_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(SidebarProps::ContentMargin())); @@ -1256,7 +1262,7 @@ public: Bind(wxEVT_PAINT, [this](wxPaintEvent& evt) { wxPaintDC dc(this); - dc.SetPen(StateColor::darkModeColorFor(wxColour("#DBDBDB"))); // ORCA match popup border color + dc.SetPen(StateColor::darkModeColorFor(wxColour("#009688"))); // ORCA match popup border color dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); }); @@ -1310,29 +1316,25 @@ public: }; ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title) - : StaticGroup(parent, wxID_ANY, wxString()) + : StaticBox(parent) { SetFont(Label::Body_10); SetForegroundColour(wxColour("#CECECE")); SetBorderColor(wxColour("#EEEEEE")); SetCornerRadius(FromDIP(PRINTER_PANEL_RADIUS)); // ORCA match radius with other boxes ShowBadge(true); + SetTopMargin(FromDIP(7)); // ORCA - // The title lives in an interactive row inside the card (with the nozzle-count badge and its edit - // button) instead of being painted on the border by StaticGroup. + // The title lives in an interactive row inside the card (with the nozzle-count badge and its edit button) hover_label = new HoverLabel(this, title); + hover_label->SetPosition(wxPoint(FromDIP(PRINTER_PANEL_RADIUS), 0)); // position it without putting in a sizer so it will look like title // Nozzle - wxStaticText *label_diameter = new wxStaticText(this, wxID_ANY, _L("Diameter")); - label_diameter->SetFont(Label::Body_14); - label_diameter->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); - if (index >= 0) label_diameter->SetMinSize({FromDIP(80), -1}); auto combo_diameter = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); this->combo_diameter = combo_diameter; - wxStaticText *label_flow = new wxStaticText(this, wxID_ANY, _L("Flow")); - label_flow->SetFont(Label::Body_14); - label_flow->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); - if (index >= 0) label_flow->SetMinSize({FromDIP(80), -1}); + combo_diameter->SetToolTip(_L("Diameter")); + + // Flow auto combo_flow = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); combo_flow->GetDropDown().SetUseContentWidth(true); combo_flow->Bind(wxEVT_COMBOBOX, [index, combo_flow](wxCommandEvent &evt) { @@ -1349,51 +1351,75 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title } }); this->combo_flow = combo_flow; + combo_flow->SetToolTip(_L("Flow")); // AMS - wxStaticText *label_ams = new wxStaticText(this, wxID_ANY, _L("AMS")); - label_ams->SetFont(Label::Body_14); - label_ams->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); - //label_ams->SetMinSize({FromDIP(70), -1}); + auto ams_panel = new wxPanel(this, wxID_ANY); + ams_panel->SetBackgroundColour(*wxWHITE); + + ams_label = new wxStaticText(ams_panel, wxID_ANY, _L("AMS")); + ams_label->SetFont(Label::Body_14); + ams_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + + // AMS not installed message + ams_not_installed_msg = new wxStaticText(ams_panel, wxID_ANY, _L("Not installed")); + ams_not_installed_msg->SetFont(Label::Body_14); + ams_not_installed_msg->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B"))); + if (index >= 0) { - btn_edit = new ScalableButton(this, wxID_ANY, "dot"); + btn_edit = new ScalableButton(ams_panel, wxID_ANY, "edit"); + btn_edit->SetMinSize(ams_label->GetSize()); btn_edit->SetBackgroundColour(extruder_group_chip_bg()); btn_edit->Hide(); - btn_edit->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, index](auto &evt) { + btn_edit->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, index, combo_diameter](auto &evt) { PopupWindow *window = new AMSCountPopupWindow(this, index); - auto size = GetSize(); - auto pos = ClientToScreen({0, size.y + 12}); + auto size = GetSize(); + auto pos = ClientToScreen({0, size.y - FromDIP(8) - combo_diameter->GetSize().y}); size.SetWidth(size.GetWidth() + FromDIP(10)); window->Position(pos, {0, 0}); window->Popup(); }); auto hovered = std::make_shared(); - for (wxWindow *w : std::initializer_list{this, label_diameter, combo_diameter, label_flow, combo_flow, btn_edit, label_ams}) { - w->Bind(wxEVT_ENTER_WINDOW, [w, hovered, this](wxMouseEvent &evt) { *hovered = w; btn_edit->SetBitmap_("edit"); }); - w->Bind(wxEVT_LEAVE_WINDOW, [w, hovered, this](wxMouseEvent &evt) { if (*hovered == w) { btn_edit->SetBitmap_("dot"); *hovered = nullptr; } }); + for (wxWindow *w : std::initializer_list{this, btn_edit, ams_not_installed_msg, ams_label, ams_panel}) { + // ORCA using CallAfter fixes crash on linux while clicking edit button + w->Bind(wxEVT_ENTER_WINDOW, [w, hovered, this](wxMouseEvent &evt) { + *hovered = w; + this->CallAfter([this]() { + btn_edit->Show(); + ams_label->Hide(); + hsizer_ams->Layout(); + }); + }); + w->Bind(wxEVT_LEAVE_WINDOW, [w, hovered, this](wxMouseEvent &evt) { + if (*hovered == w) { + *hovered = nullptr; + this->CallAfter([this]() { + btn_edit->Hide(); + ams_label->Show(); + hsizer_ams->Layout(); + }); + } + }); } } - // AMS not installed message - ams_not_installed_msg = new wxStaticText(this, wxID_ANY, _L("Not installed")); - ams_not_installed_msg->SetFont(Label::Body_14); - ams_not_installed_msg->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); - // AMS group for (size_t i = 0; i < 4; ++i) { - ams[i] = new AMSPreview(this, wxID_ANY, AMSinfo(), AMSModel::GENERIC_AMS); + ams[i] = new AMSPreview(ams_panel, wxID_ANY, AMSinfo(), AMSModel::GENERIC_AMS); ams[i]->Close(); } hsizer_ams = new wxBoxSizer(wxHORIZONTAL); hsizer_ams->SetMinSize(0, ams[0]->GetMinHeight()); - hsizer_ams->Add(label_ams, 0, wxALIGN_CENTER); + hsizer_ams->Add(ams_label, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(5)); if (btn_edit) - hsizer_ams->Add(btn_edit, 0, wxLEFT | wxALIGN_CENTER, FromDIP(2)); - hsizer_ams->Add(ams_not_installed_msg, 0, wxALIGN_CENTER); + hsizer_ams->Add(btn_edit, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(5)); + hsizer_ams->Add(ams_not_installed_msg, 1, wxALIGN_CENTER); - btn_up = new ScalableButton(this, wxID_ANY, "page_up", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14); + ams_panel->SetSizer(hsizer_ams); + + btn_up = new ScalableButton(ams_panel, wxID_ANY, "page_up", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14); btn_up->SetBackgroundColour(*wxWHITE); btn_up->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) { if (page_cur > 0) @@ -1401,7 +1427,7 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title update_ams(); }); btn_up->Hide(); - btn_down = new ScalableButton(this, wxID_ANY, "page_down", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14); + btn_down = new ScalableButton(ams_panel, wxID_ANY, "page_down", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14); btn_down->SetBackgroundColour(*wxWHITE); btn_down->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) { if (page_cur + 1 < page_num) @@ -1410,31 +1436,24 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title }); btn_down->Hide(); - wxBoxSizer *hsizer_diameter = new wxBoxSizer(wxHORIZONTAL); - hsizer_diameter->Add(label_diameter, 0, wxALIGN_CENTER); - hsizer_diameter->Add(combo_diameter, 1, wxEXPAND); - wxBoxSizer * hsizer_nozzle = new wxBoxSizer(wxHORIZONTAL); - hsizer_nozzle->Add(label_flow, 0, wxALIGN_CENTER); - hsizer_nozzle->Add(combo_flow, 1, wxEXPAND); + wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); + + hsizer->Add(combo_diameter, 1, wxRIGHT, FromDIP(5)); + hsizer->Add(combo_flow , 1); + + vsizer->AddSpacer(FromDIP(16)); // spacing for title and control if (index < 0) { - label_ams->Hide(); - ams_not_installed_msg->Hide(); - wxStaticBoxSizer *vsizer = new wxStaticBoxSizer(this, wxVERTICAL); - wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); - hsizer->Add(hsizer_diameter, 1, wxEXPAND | wxTOP| wxBOTTOM, FromDIP(8)); - hsizer->Add(hsizer_nozzle, 1, wxEXPAND | wxALL, FromDIP(8)); - hsizer->AddSpacer(FromDIP(2)); // Avoid badge - vsizer->Add(hover_label, 0, wxLEFT | wxALL, FromDIP(2)); - vsizer->Add(hsizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(2)); - this->sizer = vsizer; + ams_panel->Hide(); } else { - wxStaticBoxSizer *vsizer = new wxStaticBoxSizer(this, wxVERTICAL); - vsizer->Add(hover_label, 0, wxLEFT | wxALL, FromDIP(2)); - vsizer->Add(hsizer_ams, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, FromDIP(2)); - vsizer->Add(hsizer_diameter, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, FromDIP(2)); - vsizer->Add(hsizer_nozzle, 0, wxEXPAND | wxALL, FromDIP(2)); - this->sizer = vsizer; + vsizer->Add(ams_panel, 0, wxEXPAND | wxLEFT | wxRIGHT , FromDIP(5)); + vsizer->AddSpacer(FromDIP(2)); } + vsizer->Add(hsizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5)); + + SetSizer(vsizer); + Layout(); + AMSCountPopupWindow::UpdateAMSCount(index < 0 ? 0 : index, this); } @@ -1505,7 +1524,7 @@ void ExtruderGroup::update_ams() } } - sizer->Layout(); + Layout(); } void ExtruderGroup::sync_ams(MachineObject const *obj, std::vector const &ams4, std::vector const &ams1) diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp index 9278565c47..316389d65c 100644 --- a/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp @@ -9,6 +9,7 @@ #include "../wxExtensions.hpp" #include "Button.hpp" #include "Label.hpp" +#include "ComboBox.hpp" #include "StaticBox.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Utils.hpp" @@ -77,13 +78,16 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( wxPanel *content = new wxPanel(this); content->SetBackgroundColour(*wxWHITE); - wxBitmap nozzle_bmp = create_scaled_bitmap("hotend_thumbnail", nullptr, FromDIP(60)); + wxBitmap nozzle_bmp = create_scaled_bitmap("hotend_thumbnail", nullptr, 60); auto *nozzle_icon = new wxStaticBitmap(content, wxID_ANY, nozzle_bmp); wxBoxSizer *content_sizer = new wxBoxSizer(wxHORIZONTAL); content->SetSizer(content_sizer); wxBoxSizer *choice_sizer = new wxBoxSizer(wxVERTICAL); - choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L("Please set nozzle count")), 0, wxALL | wxALIGN_LEFT, FromDIP(10)); + auto nozzle_label = new wxStaticText(content, wxID_ANY, _L("Please set nozzle count")); + nozzle_label->SetFont(Label::Body_14); + nozzle_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + choice_sizer->Add(nozzle_label, 0, wxTOP | wxRIGHT, FromDIP(15)); wxArrayString nozzle_choices; for (int i = 0; i <= max_nozzle_count; ++i) @@ -92,16 +96,32 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( // A Hybrid extruder mixes Standard and High Flow nozzles, so it gets both count choices; the concrete // types get exactly one. if (volume_type == nvtStandard || volume_type == nvtHybrid) { - choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtStandard))), 0, wxALL | wxALIGN_LEFT, FromDIP(5)); - m_standard_choice = new wxChoice(content, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(100), -1), nozzle_choices); + wxBoxSizer *standard_sizer = new wxBoxSizer(wxHORIZONTAL); + auto standard_label = new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtStandard)), wxDefaultPosition, wxSize(FromDIP(100), -1)); + standard_label->SetFont(Label::Body_14); + standard_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + standard_sizer->Add(standard_label, 0, wxALIGN_CENTER_VERTICAL); + m_standard_choice = new ComboBox(content, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1), 0, nullptr, wxCB_READONLY); + std::vector::iterator iter; + for (iter = nozzle_choices.begin(); iter != nozzle_choices.end(); iter++) + m_standard_choice->Append(*iter); m_standard_choice->SetSelection(standard_count); - choice_sizer->Add(m_standard_choice, 0, wxLEFT | wxBOTTOM | wxRIGHT, FromDIP(10)); + standard_sizer->Add(m_standard_choice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); + choice_sizer->Add(standard_sizer, 0, wxTOP | wxRIGHT, FromDIP(15)); } if (volume_type == nvtHighFlow || volume_type == nvtHybrid) { - choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtHighFlow))), 0, wxALL | wxALIGN_LEFT, FromDIP(5)); - m_highflow_choice = new wxChoice(content, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(100), -1), nozzle_choices); + wxBoxSizer *highflow_sizer = new wxBoxSizer(wxHORIZONTAL); + auto highflow_label = new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtHighFlow)), wxDefaultPosition, wxSize(FromDIP(100), -1)); + highflow_label->SetFont(Label::Body_14); + highflow_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + highflow_sizer->Add(highflow_label, 0, wxALIGN_CENTER_VERTICAL); + m_highflow_choice = new ComboBox(content, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1), 0, nullptr, wxCB_READONLY); + std::vector::iterator iter; + for (iter = nozzle_choices.begin(); iter != nozzle_choices.end(); iter++) + m_highflow_choice->Append(*iter); m_highflow_choice->SetSelection(highflow_count); - choice_sizer->Add(m_highflow_choice, 0, wxLEFT | wxBOTTOM | wxRIGHT, FromDIP(10)); + highflow_sizer->Add(m_highflow_choice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); + choice_sizer->Add(highflow_sizer, 0, wxTOP | wxRIGHT, FromDIP(15)); } m_error_label = new wxStaticText(this, wxID_ANY, ""); @@ -128,12 +148,12 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( }; if (m_standard_choice) - m_standard_choice->Bind(wxEVT_CHOICE, [this, update_nozzle_error](wxCommandEvent &e) { + m_standard_choice->Bind(wxEVT_COMBOBOX, [this, update_nozzle_error](wxCommandEvent &e) { update_nozzle_error(m_standard_choice->GetSelection(), m_highflow_choice ? m_highflow_choice->GetSelection() : 0); e.Skip(); }); if (m_highflow_choice) - m_highflow_choice->Bind(wxEVT_CHOICE, [this, update_nozzle_error](wxCommandEvent &e) { + m_highflow_choice->Bind(wxEVT_COMBOBOX, [this, update_nozzle_error](wxCommandEvent &e) { update_nozzle_error(m_standard_choice ? m_standard_choice->GetSelection() : 0, m_highflow_choice->GetSelection()); e.Skip(); }); @@ -142,13 +162,13 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( content_sizer->Add(choice_sizer, 0, wxALIGN_CENTRE_VERTICAL); m_confirm_btn = new Button(this, _L("Confirm")); - m_confirm_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window); + m_confirm_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Choice); m_confirm_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { EndModal(wxID_OK); }); wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(content, 1, wxEXPAND); - main_sizer->Add(m_error_label, 0, wxALL, FromDIP(5)); - main_sizer->Add(m_confirm_btn, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, FromDIP(20)); + main_sizer->Add(m_error_label, 0, wxALIGN_RIGHT | wxALL, FromDIP(5)); + main_sizer->Add(m_confirm_btn, 0, wxALIGN_RIGHT | wxALL, FromDIP(15)); SetSizerAndFit(main_sizer); CentreOnParent(); diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp index 3e2e41ccb7..5a3e9374a7 100644 --- a/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp @@ -31,12 +31,12 @@ #include #include -class wxChoice; class wxStaticText; class wxStaticBitmap; class Button; // global widget (src/slic3r/GUI/Widgets/Button.hpp), not in the Slic3r::GUI namespace class Label; // global widget (src/slic3r/GUI/Widgets/Label.hpp) class StaticBox; +class ComboBox; namespace Slic3r { class PresetBundle; @@ -70,8 +70,8 @@ public: int GetNozzleCount(NozzleVolumeType volume_type) const; private: - wxChoice *m_standard_choice{nullptr}; - wxChoice *m_highflow_choice{nullptr}; + ComboBox *m_standard_choice{nullptr}; + ComboBox *m_highflow_choice{nullptr}; Button *m_confirm_btn{nullptr}; wxStaticText *m_error_label{nullptr}; }; diff --git a/src/slic3r/GUI/Widgets/StaticBox.cpp b/src/slic3r/GUI/Widgets/StaticBox.cpp index f6e7ca67f6..75953ceb3f 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.cpp +++ b/src/slic3r/GUI/Widgets/StaticBox.cpp @@ -53,6 +53,13 @@ void StaticBox::SetCornerRadius(double radius) Refresh(); } +// ORCA use when adding widgets to top to show it like LabeledStaticBox +void StaticBox::SetTopMargin(int margin) +{ + this->top_margin = margin; + Refresh(); +} + void StaticBox::SetBorderStyle(wxPenStyle style) { border_style = style; @@ -198,7 +205,8 @@ void StaticBox::doRender(wxDC& dc) int states = state_handler.states(); if (background_color2.count() == 0) { if ((border_width && border_color.count() > 0) || background_color.count() > 0) { - wxRect rc(0, 0, size.x, size.y); + int topM = top_margin > 0 ? top_margin : 0; + wxRect rc(0, topM, size.x, size.y - topM); if (border_width && border_color.count() > 0) { const double scale = dc.GetContentScaleFactor(); @@ -245,6 +253,6 @@ void StaticBox::doRender(wxDC& dc) if (badge.bmp().IsOk()) { auto s = badge.bmp().GetScaledSize(); - dc.DrawBitmap(badge.bmp(), size.x - s.x, 0); + dc.DrawBitmap(badge.bmp(), size.x - s.x, top_margin > 0 ? top_margin : 0); } } diff --git a/src/slic3r/GUI/Widgets/StaticBox.hpp b/src/slic3r/GUI/Widgets/StaticBox.hpp index 363d431c8e..b41c18ccfd 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.hpp +++ b/src/slic3r/GUI/Widgets/StaticBox.hpp @@ -27,6 +27,8 @@ public: void SetBorderWidth(int width); + void SetTopMargin(int margin); // ORCA + void SetBorderColor(StateColor const & color); void SetBorderColorNormal(wxColor const &color); @@ -57,6 +59,7 @@ protected: protected: double radius; int border_width = 1; + int top_margin = 1; wxPenStyle border_style = wxPENSTYLE_SOLID; StateHandler state_handler; StateColor border_color; diff --git a/src/slic3r/GUI/Widgets/StaticGroup.cpp b/src/slic3r/GUI/Widgets/StaticGroup.cpp deleted file mode 100644 index 69f6137939..0000000000 --- a/src/slic3r/GUI/Widgets/StaticGroup.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "StaticGroup.hpp" - -StaticGroup::StaticGroup(wxWindow *parent, wxWindowID id, const wxString &label) - : LabeledStaticBox(parent, label) -{ - SetBackgroundColour(*wxWHITE); - SetForegroundColour("#CECECE"); -} - -void StaticGroup::ShowBadge(bool show) -{ - if (show && badge.name() != "badge") { - badge = ScalableBitmap(this, "badge", 18); - Refresh(); - } else if (!show && !badge.name().empty()) { - badge = ScalableBitmap{}; - Refresh(); - } -} - -void StaticGroup::DrawBorderAndLabel(wxDC& dc) -{ - LabeledStaticBox::DrawBorderAndLabel(dc); - if (badge.bmp().IsOk()) { - auto s = badge.bmp().GetScaledSize(); - dc.DrawBitmap(badge.bmp(), GetSize().x - s.x, std::max(0, m_pos.y) + m_label_height / 2); - } -} diff --git a/src/slic3r/GUI/Widgets/StaticGroup.hpp b/src/slic3r/GUI/Widgets/StaticGroup.hpp deleted file mode 100644 index 9c98a733b2..0000000000 --- a/src/slic3r/GUI/Widgets/StaticGroup.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef slic3r_GUI_StaticGroup_hpp_ -#define slic3r_GUI_StaticGroup_hpp_ - -#include "../wxExtensions.hpp" - -#include "LabeledStaticBox.hpp" - -class StaticGroup : public LabeledStaticBox -{ -public: - StaticGroup(wxWindow *parent, wxWindowID id, const wxString &label); - void ShowBadge(bool show); - -private: - void DrawBorderAndLabel(wxDC& dc) override; - ScalableBitmap badge; -}; - -#endif // !slic3r_GUI_StaticGroup_hpp_