diff --git a/docs/doxygen/overviews/high_dpi.md b/docs/doxygen/overviews/high_dpi.md index ffc6e8fed0..58960a1a09 100644 --- a/docs/doxygen/overviews/high_dpi.md +++ b/docs/doxygen/overviews/high_dpi.md @@ -299,7 +299,8 @@ programs involves doing at least the following: wxArtProvider::CreateBitmapBundle() (and, of course, return multiple bitmaps from it) instead of wxArtProvider::CreateBitmap(). 4. Removing any calls to wxToolBar::SetToolBitmapSize() or, equivalently, - `` attributes from the XRC, as this forces unwanted scaling. + `` attributes from the XRC, as this overrides the best size + determination and may result in suboptimal appearance. diff --git a/interface/wx/toolbar.h b/interface/wx/toolbar.h index c021c1ec56..d67c92b178 100644 --- a/interface/wx/toolbar.h +++ b/interface/wx/toolbar.h @@ -882,15 +882,15 @@ public: It is usually unnecessary to call this function, as the tools will always be made big enough to fit the size of the bitmaps used in them. - Moreover, calling it may force wxToolBar to scale its images, even - using non-integer scaling factor, which will usually look bad, instead - of adapting the image size to the current DPI scaling in order to avoid - doing this. + Moreover, calling it forces wxToolBar to scale its images in high DPI + using the provided size, instead of letting wxBitmapBundle used for the + tool bitmaps determine the best suitable bitmap size, which may result + in suboptimal appearance. If you do call it, it must be done before toolbar is Realize()'d. Example of using this function to force the bitmaps to be at least - 32 pixels wide and tall: + 32 pixels wide and tall (at normal DPI): @code toolbar->SetToolBitmapSize(FromDIP(wxSize(32, 32))); toolbar->AddTool(wxID_NEW, "New", wxBitmapBundle::FromXXX(...)); @@ -898,9 +898,6 @@ public: toolbar->Realize(); @endcode - Note that this example would scale bitmaps to 48 pixels when using 150% - DPI scaling, which wouldn't happen without calling SetToolBitmapSize(). - @param size The size of the bitmaps in the toolbar in logical pixels. diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index 1aaf478555..673022012a 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -475,7 +475,23 @@ void wxToolBarBase::AdjustToolBitmapSize() bundles.push_back(bmp); } - if ( !bundles.empty() ) + if ( bundles.empty() ) + return; + + wxSize sizeNeeded; + + if ( m_requestedBitmapSize != wxSize(0, 0) ) + { + // If we have a fixed requested bitmap size, use it, but scale it by + // integer factor only, as otherwise we'd force fractional (and hence + // ugly looking) scaling here whenever fractional DPI scaling is used. + + // We want to round 1.5 down to 1, but 1.75 up to 2. + int scaleFactorRoundedDown = + static_cast(ceil(2*GetDPIScaleFactor())) / 2; + sizeNeeded = m_requestedBitmapSize*scaleFactorRoundedDown; + } + else // Determine the best size to use from the bitmaps we have. { wxSize sizePreferred = wxBitmapBundle::GetConsensusSizeFor ( @@ -492,22 +508,17 @@ void wxToolBarBase::AdjustToolBitmapSize() // scale factor may be different from 1) use this size at all // currently, so it shouldn't matter. But if/when they are modified to // use the size computed here, this would need to be revisited. - sizePreferred = FromPhys(sizePreferred); - - // Don't decrease the bitmap below the size requested by the application - // as using larger bitmaps shouldn't shrink them to the small default - // size. - sizePreferred.IncTo(FromDIP(m_requestedBitmapSize)); - - // No need to change the bitmaps size if it doesn't really change. - if ( sizePreferred == sizeOrig ) - return; + sizeNeeded = FromPhys(sizePreferred); + } + // No need to change the bitmaps size if it doesn't really change. + if ( sizeNeeded != sizeOrig ) + { // Call DoSetToolBitmapSize() and not SetToolBitmapSize() to avoid // changing the requested bitmap size: if we set our own adjusted size // as the preferred one, we wouldn't decrease it later even if we ought // to, as when moving from a monitor with higher DPI to a lower-DPI one. - DoSetToolBitmapSize(sizePreferred); + DoSetToolBitmapSize(sizeNeeded); } }