From f02aa7200e5373275417bf45f818d4d5bc4119a3 Mon Sep 17 00:00:00 2001 From: yw4z Date: Tue, 14 Apr 2026 17:48:38 +0300 Subject: [PATCH] Fix over scaled controls on windows (#13117) init --- src/slic3r/GUI/BBLTopbar.cpp | 7 +++-- src/slic3r/GUI/Widgets/SwitchButton.cpp | 6 ++++ src/slic3r/GUI/wxExtensions.cpp | 40 +++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp index 3bdb30d7f4..bc0b416267 100644 --- a/src/slic3r/GUI/BBLTopbar.cpp +++ b/src/slic3r/GUI/BBLTopbar.cpp @@ -129,9 +129,10 @@ void BBLTopbarArt::DrawButton(wxDC& dc, wxWindow* wnd, const wxAuiToolBarItem& i int bmpX = 0, bmpY = 0; int textX = 0, textY = 0; - const wxBitmap& bmp = item.GetState() & wxAUI_BUTTON_STATE_DISABLED - ? item.GetDisabledBitmap() - : item.GetBitmap(); + // ORCA resolves the toolbar item bitmap using the actual window DPI context used for painting. + // GetBitmap() / GetDisabledBitmap() was using internal window pointer (m_window), not the paint-time wnd + // m_window was created before final DPI context was known so items not scales properly + const wxBitmap bmp = item.GetCurrentBitmapFor(wnd); const wxSize bmpSize = bmp.IsOk() ? bmp.GetScaledSize() : wxSize(0, 0); diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp index 3aafa0fbc1..bedc068e1b 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp @@ -138,6 +138,10 @@ void SwitchButton::Rescale() memdc.SelectObject(bmp); #endif memdc.SetFont(dc.GetFont()); +#ifdef __WXMSW__ + const double scale = GetDPIScaleFactor(); + fontScale = scale; +#endif if (fontScale) { memdc.SetFont(dc.GetFont().Scaled(fontScale)); textSize[0] = memdc.GetTextExtent(labels[0]); @@ -176,6 +180,8 @@ void SwitchButton::Rescale() memdc.SelectObject(wxNullBitmap); #ifdef __WXOSX__ bmp = wxBitmap(bmp.ConvertToImage(), -1, scale); +#elif defined(__WXMSW__) + bmp.SetScaleFactor(scale); // ORCA #endif (i == 0 ? m_off : m_on).bmp() = bmp; } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 1a6037184d..ee256a9ace 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -468,6 +468,10 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, throw Slic3r::RuntimeError("Could not load bitmap: " + bmp_name); } +#ifdef __WXMSW__ + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + bmp->SetScaleFactor(win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0)); +#endif return *bmp; } @@ -487,6 +491,10 @@ wxBitmap create_scaled_bitmap2(const std::string& bmp_name_in, Slic3r::GUI::Bitm BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Could not load bitmap: " << bmp_name; throw Slic3r::RuntimeError("Could not load bitmap: " + bmp_name); } +#ifdef __WXMSW__ + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + bmp->SetScaleFactor(win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0)); +#endif return *bmp; } @@ -500,7 +508,8 @@ wxBitmap* get_default_extruder_color_icon(bool thin_icon/* = false*/) const int icon_height = lround(2 * em); bool dark_mode = Slic3r::GUI::wxGetApp().dark_mode(); - wxClientDC cdc((wxWindow*)Slic3r::GUI::wxGetApp().mainframe); + auto win = (wxWindow*)Slic3r::GUI::wxGetApp().mainframe; + wxClientDC cdc(win); wxMemoryDC dc(&cdc); dc.SetFont(::Label::Body_12); @@ -526,6 +535,12 @@ wxBitmap* get_default_extruder_color_icon(bool thin_icon/* = false*/) dc.SelectObject(wxNullBitmap); } + #ifdef __WXMSW__ + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + double scale = win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0); + bitmap->SetScaleFactor(scale); + #endif + return bitmap; } @@ -633,6 +648,9 @@ wxBitmap *get_extruder_color_icon(std::vector colors, bool is_gradi bitmap_key += "h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) + "-i" + label; wxBitmap *bitmap = bmp_cache.find(bitmap_key); + #ifdef __WXMSW__ + auto win = (wxWindow *) Slic3r::GUI::wxGetApp().mainframe; + #endif if (bitmap == nullptr) { std::vector wx_colors; @@ -656,8 +674,11 @@ wxBitmap *get_extruder_color_icon(std::vector colors, bool is_gradi #ifndef __WXMSW__ wxMemoryDC dc(base_bitmap); #else - wxClientDC cdc((wxWindow *) Slic3r::GUI::wxGetApp().mainframe); + wxClientDC cdc(win); wxMemoryDC dc(&cdc); + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + double scale = win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0); + base_bitmap.SetScaleFactor(scale); dc.SelectObject(base_bitmap); #endif @@ -694,6 +715,11 @@ wxBitmap *get_extruder_color_icon(std::vector colors, bool is_gradi // cache result bitmap = bmp_cache.insert(bitmap_key, base_bitmap); } + #ifdef __WXMSW__ + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + double scale = win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0); + bitmap->SetScaleFactor(scale); + #endif return bitmap; } @@ -704,6 +730,9 @@ wxBitmap *get_extruder_color_icon(std::string color, std::string label, int icon std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) + "-i" + label; wxBitmap *bitmap = bmp_cache.find(bitmap_key); + #ifdef __WXMSW__ + auto win = (wxWindow *) Slic3r::GUI::wxGetApp().mainframe; + #endif if (bitmap == nullptr) { // Paint the color icon. // Slic3r::GUI::BitmapCache::parse_color(color, rgb); @@ -714,7 +743,7 @@ wxBitmap *get_extruder_color_icon(std::string color, std::string label, int icon bitmap->UseAlpha(); wxMemoryDC dc(*bitmap); #elif defined(__WXMSW__) - wxClientDC cdc((wxWindow *) Slic3r::GUI::wxGetApp().mainframe); + wxClientDC cdc(win); wxMemoryDC dc(&cdc); dc.SelectObject(*bitmap); #else @@ -748,6 +777,11 @@ wxBitmap *get_extruder_color_icon(std::string color, std::string label, int icon dc.DrawText(label, (icon_width - size.x) / 2, (icon_height - size.y) / 2); dc.SelectObject(wxNullBitmap); } + #ifdef __WXMSW__ + // ORCA MSW needs to set scale factor for bitmaps loaded from cache because they arent auto scaled by wxBitmapBundle like bitmaps + double scale = win ? win->GetDPIScaleFactor() : (wxWindow::FromDIP(100, nullptr) / 100.0); + bitmap->SetScaleFactor(scale); + #endif return bitmap; } void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl,