From 795514900da47f420739f2d1b407b7f8250cd19e Mon Sep 17 00:00:00 2001 From: Lam Wei Lun Date: Tue, 25 Aug 2026 15:18:38 +0800 Subject: [PATCH] Fix Windows paint on resize issue. Automatically resize to fit tabs and button content --- src/slic3r/GUI/PublishSettingsDialog.cpp | 40 +++++++++++++++++++++--- src/slic3r/GUI/PublishSettingsDialog.hpp | 2 ++ src/slic3r/GUI/Widgets/StaticBox.cpp | 7 +++++ src/slic3r/GUI/Widgets/StaticBox.hpp | 2 ++ src/slic3r/GUI/Widgets/TabCtrl.cpp | 9 ++++++ src/slic3r/GUI/Widgets/TabCtrl.hpp | 2 ++ 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/PublishSettingsDialog.cpp b/src/slic3r/GUI/PublishSettingsDialog.cpp index 08adae903b..0ebb784b01 100644 --- a/src/slic3r/GUI/PublishSettingsDialog.cpp +++ b/src/slic3r/GUI/PublishSettingsDialog.cpp @@ -17,6 +17,7 @@ #include "libslic3r/PublishSettings.hpp" #include +#include #include #include @@ -97,7 +98,7 @@ PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent) _L("Publish 3MF..."), wxDefaultPosition, wxDefaultSize, - wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) + wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) , m_search(this, "search", 16) , m_menu(this, "filter", 16) { @@ -193,11 +194,42 @@ PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent) w_sizer->Add(dlg_btns, 0, wxEXPAND); SetSizerAndFit(w_sizer); - SetMinSize(FromDIP(wxSize(600, 500))); - SetSize(FromDIP(wxSize(600, 500))); // initial size only; the dialog is resizable + fit_to_content(); // initial size only; the dialog is resizable wxGetApp().UpdateDlgDarkUI(this); } +// Size the window to its content: width follows the widest tab strip so no filament tab is +// hidden (TabCtrl::relayout hides overflowing buttons), height scales proportionally. Both +// are floored at the 600x500 base and capped at hard DIP limits - deliberately not the whole +// display - with one last-resort clamp so the dialog can never open larger than the screen. +// Also owns the resize floor: the window cannot be resized below what the tabs need, so +// shrinking never re-hides a filament tab. +void PublishSettingsDialog::fit_to_content() +{ + static const wxSize BASE{600, 500}; + static const wxSize CAP{1300, 850}; + + int strip = m_outer_tabs->buttons_best_width(); + for (const SectionGroup& section : m_sections) + strip = std::max(strip, section.tabs->buttons_best_width()); + + // Minimum width: whatever keeps every tab visible (never below the base). strip is device + // pixels (Button min sizes); BASE/CAP are DIP and converted over. + const int min_w = std::max(strip + 2 * FromDIP(10), FromDIP(BASE.x)); + + // Initial size: prefer proportional growth within the caps. + const int w = std::clamp(min_w, FromDIP(BASE.x), FromDIP(CAP.x)); + const double f = double(w) / FromDIP(BASE.x); + const int h = std::clamp(int(FromDIP(BASE.y) * f), FromDIP(BASE.y), FromDIP(CAP.y)); + + const wxRect area = wxDisplay(this).GetClientArea(); + const int max_w = area.width * 9 / 10; + const int max_h = area.height * 9 / 10; + + SetMinSize(wxSize(std::min(min_w, max_w), std::min(FromDIP(BASE.y), max_h))); + SetSize(std::min(w, max_w), std::min(h, max_h)); +} + PublishSettingsDialog::~PublishSettingsDialog() {} void PublishSettingsDialog::build_option_model() @@ -1059,7 +1091,7 @@ void PublishSettingsDialog::on_dpi_changed(const wxRect& suggested_rect) } } - SetMinSize(FromDIP(wxSize(600, 500))); + fit_to_content(); // tab buttons' min widths grew with the DPI: re-fit (incl. resize floor) Refresh(); } diff --git a/src/slic3r/GUI/PublishSettingsDialog.hpp b/src/slic3r/GUI/PublishSettingsDialog.hpp index 312931c0c1..2b094da75b 100644 --- a/src/slic3r/GUI/PublishSettingsDialog.hpp +++ b/src/slic3r/GUI/PublishSettingsDialog.hpp @@ -48,6 +48,8 @@ protected: void on_dpi_changed(const wxRect& suggested_rect) override; private: + void fit_to_content(); + // Which part of the settings the row/category came from. enum class Section { Print, Printer, Material }; diff --git a/src/slic3r/GUI/Widgets/StaticBox.cpp b/src/slic3r/GUI/Widgets/StaticBox.cpp index 6391c1a8c4..f6e7ca67f6 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.cpp +++ b/src/slic3r/GUI/Widgets/StaticBox.cpp @@ -7,6 +7,7 @@ BEGIN_EVENT_TABLE(StaticBox, wxWindow) // catch paint events //EVT_ERASE_BACKGROUND(StaticBox::eraseEvent) +EVT_SIZE(StaticBox::sizeEvent) EVT_PAINT(StaticBox::paintEvent) END_EVENT_TABLE() @@ -140,6 +141,12 @@ void StaticBox::eraseEvent(wxEraseEvent& evt) #endif } +void StaticBox::sizeEvent(wxSizeEvent& evt) +{ + Refresh(); + evt.Skip(); +} + void StaticBox::paintEvent(wxPaintEvent& evt) { // depending on your system you may need to look at double-buffered dcs diff --git a/src/slic3r/GUI/Widgets/StaticBox.hpp b/src/slic3r/GUI/Widgets/StaticBox.hpp index b7cdee34ef..363d431c8e 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.hpp +++ b/src/slic3r/GUI/Widgets/StaticBox.hpp @@ -46,6 +46,8 @@ public: protected: void eraseEvent(wxEraseEvent& evt); + void sizeEvent(wxSizeEvent& evt); + void paintEvent(wxPaintEvent& evt); void render(wxDC& dc); diff --git a/src/slic3r/GUI/Widgets/TabCtrl.cpp b/src/slic3r/GUI/Widgets/TabCtrl.cpp index 6aeffd2dce..5c2eb2d693 100644 --- a/src/slic3r/GUI/Widgets/TabCtrl.cpp +++ b/src/slic3r/GUI/Widgets/TabCtrl.cpp @@ -295,6 +295,15 @@ void TabCtrl::relayout() Layout(); } +int TabCtrl::buttons_best_width() const +{ + // Mirrors relayout(): a 10px leading spacer plus every button's min width and spacing. + int width = 10; + for (const Button *btn : btns) + width += btn->GetMinSize().x + TAB_BUTTON_SPACE * 2; + return width; +} + void TabCtrl::buttonClicked(wxCommandEvent &event) { SetFocus(); diff --git a/src/slic3r/GUI/Widgets/TabCtrl.hpp b/src/slic3r/GUI/Widgets/TabCtrl.hpp index e79dd1dee6..5631eeb6a7 100644 --- a/src/slic3r/GUI/Widgets/TabCtrl.hpp +++ b/src/slic3r/GUI/Widgets/TabCtrl.hpp @@ -73,6 +73,8 @@ private: void relayout(); + int buttons_best_width() const; + void buttonClicked(wxCommandEvent & event); void keyDown(wxKeyEvent &event);