Merge branch 'main' into feat/printer-agent-infra

This commit is contained in:
Ian Chua
2026-09-15 16:47:15 +08:00
committed by GitHub
31 changed files with 944 additions and 303 deletions
+3 -8
View File
@@ -2098,12 +2098,6 @@ void GLCanvas3D::render(bool only_init)
_render_selection_center();
#endif // ENABLE_RENDER_SELECTION_CENTER
// we need to set the mouse's scene position here because the depth buffer
// could be invalidated by the following gizmo render methods
// this position is used later into on_mouse() to drag the objects
if (m_picking_enabled)
m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<coord_t>());
// sidebar hints need to be rendered before the gizmos because the depth buffer
// could be invalidated by the following gizmo render methods
_render_selection_sidebar_hints();
@@ -4491,12 +4485,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box();
volume_bbox.offset(1.0);
const bool is_cut_connector_selected = m_selection.is_any_connector();
if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(m_mouse.scene_position) && !is_cut_connector_selected) {
const Vec3d scene_position = _mouse_to_3d(pos);
if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(scene_position) && !is_cut_connector_selected) {
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
// The dragging operation is initiated.
m_mouse.drag.move_volume_idx = volume_idx;
m_selection.setup_cache();
m_mouse.drag.start_position_3D = m_mouse.scene_position;
m_mouse.drag.start_position_3D = scene_position;
m_sequential_print_clearance_first_displacement = true;
m_moving = true;
-1
View File
@@ -337,7 +337,6 @@ class GLCanvas3D
bool dragging{ false };
Vec2d position{ DBL_MAX, DBL_MAX };
Vec3d scene_position{ DBL_MAX, DBL_MAX, DBL_MAX };
bool ignore_left_up{ false };
Drag drag;
bool ignore_right_up;
+2 -2
View File
@@ -1717,7 +1717,7 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode, const Dynam
return plate_extruders;
}
std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const
std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config, bool expand_mixed_slots) const
{
std::vector<int> plate_extruders;
@@ -1878,7 +1878,7 @@ std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D
// Expand mixed filament slots to their physical components. A mixed slot is virtual and
// is never loaded into a tray, so callers (AMS mapping, filament checks) must see the
// physical filaments it resolves to instead.
{
if (expand_mixed_slots) {
auto* is_mixed_opt = full_config.option<ConfigOptionBools>("filament_is_mixed");
auto* comp_strs_opt = full_config.option<ConfigOptionStrings>("filament_mixed_components");
if (is_mixed_opt && comp_strs_opt && has_any_mixed_filament(is_mixed_opt->values)) {
+2 -1
View File
@@ -350,7 +350,8 @@ public:
// get used filaments from config, 1 based idx
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
std::vector<int> get_extruders(bool conside_custom_gcode, const DynamicPrintConfig& glb_config, const DynamicPrintConfig& project_config) const;
std::vector<int> get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const;
// expand_mixed_slots = false keeps mixed filament slots as slots instead of their components.
std::vector<int> get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config, bool expand_mixed_slots = true) const;
std::vector<int> get_extruders_without_support(bool conside_custom_gcode = false) const;
// get used filaments from gcode result, 1 based idx
std::vector<int> get_used_filaments();
-3
View File
@@ -1037,9 +1037,6 @@ size_t PublishSettingsDialog::section_group_for(Section kind)
section.mixed_tabs = new TabCtrl(section.page, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_tab_style);
section.mixed_tabs->SetFont(Label::Body_14);
section.mixed_tabs->SetBackgroundColour(GetBackgroundColour());
// The mixed tabs carry full swatch compositions: give them a touch more room than the
// filament tabs so neighbouring compositions stay distinguishable (must precede AppendItem).
section.mixed_tabs->SetItemSpace(FromDIP(3));
page_sizer->Add(section.mixed_tabs, 0, wxEXPAND | wxTOP, FromDIP(2));
section.mixed_tabs->Hide();
}
+6 -3
View File
@@ -311,8 +311,11 @@ void Button::render(wxDC& dc)
}
}
auto szContent = textSize;
// Whether the measured content reserved the text/icon gap. macOS measures an empty label
// as 0-high, so the gap is skipped there; the dot must not advance past it in that case.
const bool gap_reserved = szContent.y > 0;
if (icon.bmp().IsOk()) {
if (szContent.y > 0) {
if (gap_reserved) {
//BBS norrow size between text and icon
if (vertical)
szContent.y += spacing;
@@ -357,10 +360,10 @@ void Button::render(wxDC& dc)
dc.DrawBitmap(icon.bmp(), pt);
//BBS norrow size between text and icon
if (vertical) {
pt.y += szIcon.y + spacing;
pt.y += szIcon.y + (gap_reserved ? spacing : 0);
pt.x = rcContent.x;
} else {
pt.x += szIcon.x + spacing;
pt.x += szIcon.x + (gap_reserved ? spacing : 0);
pt.y = rcContent.y;
}
}
+7 -16
View File
@@ -99,7 +99,7 @@ int TabCtrl::AppendItem(const wxString& item, int image, int selImage, void* cli
btns.push_back(btn);
if (btns.size() > 1)
sizer->GetItem(sizer->GetItemCount() - 1)->SetMinSize({0, 0});
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, item_space);
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
sizer->AddStretchSpacer(1);
relayout();
return btns.size() - 1;
@@ -256,12 +256,12 @@ void TabCtrl::relayout()
int item = sel + 1;
int first = 0;
for (int i = 0; i < item; ++i)
offset += btns[i]->GetMinSize().x + item_space * 2;
offset += btns[i]->GetMinSize().x;
if (item < btns.size())
offset += btns[item]->GetMinSize().x + item_space * 2;
offset += btns[item]->GetMinSize().x;
int width = GetSize().x;
for (int i = 0; i < btns.size(); ++i) {
auto size = btns[i]->GetMinSize().x + item_space * 2;
auto size = btns[i]->GetMinSize().x;
if (i < sel && offset > width) {
sizer->Show(i * 2 + 1, false);
sizer->Show(i * 2 + 2, false);
@@ -284,26 +284,17 @@ void TabCtrl::relayout()
if (item >= btns.size())
--item;
// Keep spacing 2 ~ 10 TAB_BUTTON_SPACE
int b = GetSize().x - offset - 10 - (item + 1 - first) * item_space * 8;
int b = GetSize().x - offset - 10 - (item + 1 - first) * 16;
sizer->GetItem(item * 2 + 2)->SetMinSize({b > 0 ? b : 0, 0});
Layout();
}
void TabCtrl::SetItemSpace(int space)
{
if (space < 0 || space == item_space)
return;
item_space = space;
relayout();
Refresh();
}
int TabCtrl::GetFullSize() const
{
// Mirrors relayout(): a 10px leading spacer plus every button's min width and spacing.
// Mirrors relayout(): a 10px leading spacer plus every button's min width.
int width = 10;
for (const Button* btn : btns)
width += btn->GetMinSize().x + item_space * 2;
width += btn->GetMinSize().x;
return width;
}
-5
View File
@@ -14,7 +14,6 @@ class TabCtrl : public StaticBox
int sel = -1;
wxFont bold;
int item_space = 2; // space around each button, both sides (SetItemSpace)
public:
TabCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0);
@@ -64,10 +63,6 @@ public:
int GetNextVisible(int item) const;
bool IsVisible(unsigned int item) const;
// Extra space around each tab button (in px on both sides). Defaults to the control-wide
// standard; call before appending items so every button picks it up.
void SetItemSpace(int space);
int GetFullSize() const;
private: