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 <timemanager.rick@gmail.com>
This commit is contained in:
yw4z
2026-09-18 23:43:42 +08:00
committed by GitHub
co-authored by Noisyfox
parent 9bd4432f27
commit c5f9257878
9 changed files with 157 additions and 155 deletions
+33 -13
View File
@@ -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<wxString>::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<wxString>::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();
+3 -3
View File
@@ -31,12 +31,12 @@
#include <unordered_map>
#include <vector>
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};
};
+10 -2
View File
@@ -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);
}
}
+3
View File
@@ -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;
-28
View File
@@ -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);
}
}
-19
View File
@@ -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_