Use wxRescaleCoord() in wxMSW DPI update code too

Use the same scaling function as elsewhere instead of using
ceil/floor().

Provide wxRescaleCoordWithFrom specialization for int to allow using it
with just single coordinates too.
This commit is contained in:
Vadim Zeitlin
2021-07-13 17:56:18 +01:00
parent 035c29e6a2
commit b9a2469ace
2 changed files with 44 additions and 27 deletions

View File

@@ -29,8 +29,9 @@
// order to allow calling To() on it.
//
// Another complication is that we want this to work for both wxSize and
// wxPoint, so wxRescaleCoord() is a overloaded and the helper classes are
// templates, with their template parameter being either one or the other.
// wxPoint, as well as for just plain coordinate values, so wxRescaleCoord() is
// an overloaded function and the helper classes are templates, with their
// template parameter being either wxSize, wxPoint or int.
namespace wxPrivate
{
@@ -72,6 +73,31 @@ private:
friend wxRescaleCoordWithValue<T>;
};
// Specialization for just a single value.
template <>
class wxRescaleCoordWithFrom<int>
{
public:
int To(wxSize newScale) const
{
return m_value == wxDefaultCoord
? wxDefaultCoord
: wxMulDivInt32(m_value, newScale.x, m_oldScale.x);
}
private:
wxRescaleCoordWithFrom(int value, wxSize oldScale)
: m_value(value), m_oldScale(oldScale)
{
}
const int m_value;
const wxSize m_oldScale;
// Only it can create objects of this class.
friend wxRescaleCoordWithValue<int>;
};
template <typename T>
class wxRescaleCoordWithValue
{
@@ -97,6 +123,11 @@ private:
} // namespace wxPrivate
inline wxPrivate::wxRescaleCoordWithValue<int> wxRescaleCoord(int coord)
{
return wxPrivate::wxRescaleCoordWithValue<int>(coord);
}
inline wxPrivate::wxRescaleCoordWithValue<wxSize> wxRescaleCoord(wxSize sz)
{
return wxPrivate::wxRescaleCoordWithValue<wxSize>(sz);

View File

@@ -82,6 +82,7 @@
#include "wx/msw/dcclient.h"
#include "wx/msw/seh.h"
#include "wx/private/textmeasure.h"
#include "wx/private/rescale.h"
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
@@ -4891,20 +4892,9 @@ void wxWindowMSW::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
}
}
// Helper function to update the given coordinate by the scaling factor if it
// is set, i.e. different from wxDefaultCoord.
static void ScaleCoordIfSet(int& coord, float scaleFactor)
{
if ( coord != wxDefaultCoord )
{
const float coordScaled = coord * scaleFactor;
coord = int(scaleFactor > 1 ? std::ceil(coordScaled) : std::floor(coordScaled));
}
}
// Called from MSWUpdateonDPIChange() to recursively update the window
// sizer and any child sizers and spacers.
static void UpdateSizerOnDPIChange(wxSizer* sizer, float scaleFactor)
static void UpdateSizerOnDPIChange(wxSizer* sizer, wxSize oldDPI, wxSize newDPI)
{
if ( !sizer )
{
@@ -4919,27 +4909,25 @@ static void UpdateSizerOnDPIChange(wxSizer* sizer, float scaleFactor)
wxSizerItem* sizerItem = node->GetData();
int border = sizerItem->GetBorder();
ScaleCoordIfSet(border, scaleFactor);
border = wxRescaleCoord(border).From(oldDPI).To(newDPI);
sizerItem->SetBorder(border);
// only scale sizers and spacers, not windows
if ( sizerItem->IsSizer() || sizerItem->IsSpacer() )
{
wxSize min = sizerItem->GetMinSize();
ScaleCoordIfSet(min.x, scaleFactor);
ScaleCoordIfSet(min.y, scaleFactor);
min = wxRescaleCoord(min).From(oldDPI).To(newDPI);
sizerItem->SetMinSize(min);
if ( sizerItem->IsSpacer() )
{
wxSize size = sizerItem->GetSize();
ScaleCoordIfSet(size.x, scaleFactor);
ScaleCoordIfSet(size.y, scaleFactor);
size = wxRescaleCoord(size).From(oldDPI).To(newDPI);
sizerItem->SetDimension(wxDefaultPosition, size);
}
// Update any child sizers if this is a sizer
UpdateSizerOnDPIChange(sizerItem->GetSizer(), scaleFactor);
UpdateSizerOnDPIChange(sizerItem->GetSizer(), oldDPI, newDPI);
}
}
}
@@ -4948,12 +4936,10 @@ void
wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
{
// update min and max size if necessary
const float scaleFactor = (float)newDPI.y / oldDPI.y;
ScaleCoordIfSet(m_minHeight, scaleFactor);
ScaleCoordIfSet(m_minWidth, scaleFactor);
ScaleCoordIfSet(m_maxHeight, scaleFactor);
ScaleCoordIfSet(m_maxWidth, scaleFactor);
m_minHeight = wxRescaleCoord(m_minHeight).From(oldDPI).To(newDPI);
m_minWidth = wxRescaleCoord(m_minWidth).From(oldDPI).To(newDPI);
m_maxHeight = wxRescaleCoord(m_maxHeight).From(oldDPI).To(newDPI);
m_maxWidth = wxRescaleCoord(m_maxWidth).From(oldDPI).To(newDPI);
InvalidateBestSize();
@@ -4961,7 +4947,7 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
MSWUpdateFontOnDPIChange(newDPI);
// update sizers
UpdateSizerOnDPIChange(GetSizer(), scaleFactor);
UpdateSizerOnDPIChange(GetSizer(), oldDPI, newDPI);
// update children
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();