diff --git a/include/wx/event.h b/include/wx/event.h index ec7fa51d9c..49f2bce205 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -3142,10 +3142,10 @@ public: // Scale the value by the ratio between new and old DPIs carried by this // event. - int ScaleX(int x) const; - int ScaleY(int y) const; + wxSize Scale(wxSize sz) const; - wxSize Scale(wxSize sz) const { return wxSize(ScaleX(sz.x), ScaleY(sz.y)); } + int ScaleX(int x) const { return Scale(wxSize(x, -1)).x; } + int ScaleY(int y) const { return Scale(wxSize(-1, y)).y; } virtual wxEvent *Clone() const wxOVERRIDE { return new wxDPIChangedEvent(*this); } diff --git a/include/wx/private/rescale.h b/include/wx/private/rescale.h index 45a5471b59..e4266921c0 100644 --- a/include/wx/private/rescale.h +++ b/include/wx/private/rescale.h @@ -18,26 +18,98 @@ #include "wx/msw/wrapwin.h" #endif +// wxRescaleCoord is used to scale the components of the given wxSize by the +// ratio between 2 scales, with rounding. It doesn't not scale the components +// if they're set to -1 (wxDefaultCoord), as this value is special in wxSize. +// +// The way it's used is special because we want to ensure there is no confusion +// between the scale being converted from and the scale being converted to, so +// instead of just using a single function, we use an intermediate object, +// which is not supposed to be used directly, but is only returned by From() in +// 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. -// Scale the given value by the ratio between 2 other values, with rounding. -// Do not scale the value if it's -1, just return it unchanged in this case. -inline int wxRescaleCoord(int n, int newScale, int oldScale) +namespace wxPrivate { - return n == -1 ? -1 : wxMulDivInt32(n, newScale, oldScale); + +template class wxRescaleCoordWithValue; + +template +class wxRescaleCoordWithFrom +{ +public: + T To(wxSize newScale) const + { + T value(m_value); + + if ( value.x != wxDefaultCoord ) + value.x = wxMulDivInt32(value.x, newScale.x, m_oldScale.x); + + if ( value.y != wxDefaultCoord ) + value.y = wxMulDivInt32(value.y, newScale.y, m_oldScale.y); + + return value; + } + + T To(int newScaleX, int newScaleY) const + { + return To(wxSize(newScaleX, newScaleY)); + } + +private: + wxRescaleCoordWithFrom(T value, wxSize oldScale) + : m_value(value), m_oldScale(oldScale) + { + } + + const T m_value; + const wxSize m_oldScale; + + // Only it can create objects of this class. + friend wxRescaleCoordWithValue; +}; + +template +class wxRescaleCoordWithValue +{ +public: + explicit wxRescaleCoordWithValue(T value) + : m_value(value) + { + } + + wxRescaleCoordWithFrom From(wxSize oldScale) + { + return wxRescaleCoordWithFrom(m_value, oldScale); + } + + wxRescaleCoordWithFrom From(int oldScaleX, int oldScaleY) + { + return From(wxSize(oldScaleX, oldScaleY)); + } + +private: + const T m_value; +}; + +} // namespace wxPrivate + +inline wxPrivate::wxRescaleCoordWithValue wxRescaleCoord(wxSize sz) +{ + return wxPrivate::wxRescaleCoordWithValue(sz); } -inline wxPoint -wxRescaleCoord(wxPoint pt, wxSize newScale, wxSize oldScale) +inline wxPrivate::wxRescaleCoordWithValue wxRescaleCoord(int x, int y) { - return wxPoint(wxRescaleCoord(pt.x, newScale.x, oldScale.x), - wxRescaleCoord(pt.y, newScale.y, oldScale.y)); + return wxPrivate::wxRescaleCoordWithValue(wxSize(x, y)); } -inline wxSize -wxRescaleCoord(wxSize sz, wxSize newScale, wxSize oldScale) +inline wxPrivate::wxRescaleCoordWithValue wxRescaleCoord(wxPoint pt) { - return wxSize(wxRescaleCoord(sz.x, newScale.x, oldScale.x), - wxRescaleCoord(sz.y, newScale.y, oldScale.y)); + return wxPrivate::wxRescaleCoordWithValue(pt); } #endif // _WX_PRIVATE_RESCALE_H_ diff --git a/src/common/event.cpp b/src/common/event.cpp index 415d883d26..2ac6d35fde 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -941,14 +941,9 @@ wxHelpEvent::Origin wxHelpEvent::GuessOrigin(Origin origin) // wxDPIChangedEvent // ---------------------------------------------------------------------------- -int wxDPIChangedEvent::ScaleX(int x) const +wxSize wxDPIChangedEvent::Scale(wxSize sz) const { - return wxRescaleCoord(x, m_newDPI.x, m_oldDPI.x); -} - -int wxDPIChangedEvent::ScaleY(int y) const -{ - return wxRescaleCoord(y, m_newDPI.y, m_oldDPI.y); + return wxRescaleCoord(sz).From(m_oldDPI).To(m_newDPI); } #endif // wxUSE_GUI diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 3ace3de1f6..bb8127670c 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -2902,9 +2902,9 @@ wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* w) { const wxSize dpi = GetDPIHelper(w); - const int baseline = wxDisplay::GetStdPPIValue(); + const wxSize baseline = wxDisplay::GetStdPPI(); - return wxRescaleCoord(sz, dpi, wxSize(baseline, baseline)); + return wxRescaleCoord(sz).From(baseline).To(dpi); } /* static */ @@ -2913,9 +2913,9 @@ wxWindowBase::ToDIP(const wxSize& sz, const wxWindowBase* w) { const wxSize dpi = GetDPIHelper(w); - const int baseline = wxDisplay::GetStdPPIValue(); + const wxSize baseline = wxDisplay::GetStdPPI(); - return wxRescaleCoord(sz, wxSize(baseline, baseline), dpi); + return wxRescaleCoord(sz).From(dpi).To(baseline); } #endif // !wxHAVE_DPI_INDEPENDENT_PIXELS @@ -2954,14 +2954,14 @@ wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) const { const wxSize base = GetDlgUnitBase(); - return wxRescaleCoord(pt, wxSize(4, 8), base); + return wxRescaleCoord(pt).From(base).To(4, 8); } wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const { const wxSize base = GetDlgUnitBase(); - return wxRescaleCoord(pt, base, wxSize(4, 8)); + return wxRescaleCoord(pt).From(4, 8).To(base); } // ---------------------------------------------------------------------------- diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 6bca3e18e2..42408a4a32 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -187,7 +187,7 @@ wxSize wxButtonBase::GetDefaultSize(wxWindow* win) // http://support.microsoft.com/default.aspx/kb/145994 for detailed // discussion. - s_sizeBtn.SetAtNewDPI(wxRescaleCoord(wxSize(50, 14), base, wxSize(4, 8))); + s_sizeBtn.SetAtNewDPI(wxRescaleCoord(50, 14).From(4, 8).To(base)); } return s_sizeBtn.Get();