Merge branch 'dpi-scale'
Add wxDPIChangedEvent::Scale() and use it in our own code. See https://github.com/wxWidgets/wxWidgets/pull/2429
This commit is contained in:
@@ -3140,6 +3140,13 @@ public:
|
|||||||
wxSize GetOldDPI() const { return m_oldDPI; }
|
wxSize GetOldDPI() const { return m_oldDPI; }
|
||||||
wxSize GetNewDPI() const { return m_newDPI; }
|
wxSize GetNewDPI() const { return m_newDPI; }
|
||||||
|
|
||||||
|
// Scale the value by the ratio between new and old DPIs carried by this
|
||||||
|
// event.
|
||||||
|
wxSize Scale(wxSize sz) const;
|
||||||
|
|
||||||
|
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); }
|
virtual wxEvent *Clone() const wxOVERRIDE { return new wxDPIChangedEvent(*this); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
146
include/wx/private/rescale.h
Normal file
146
include/wx/private/rescale.h
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/private/rescale.h
|
||||||
|
// Purpose: Helpers for rescaling coordinates
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2021-07-13
|
||||||
|
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_PRIVATE_RESCALE_H_
|
||||||
|
#define _WX_PRIVATE_RESCALE_H_
|
||||||
|
|
||||||
|
#include "wx/gdicmn.h"
|
||||||
|
#include "wx/math.h"
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
// Required in order to use wxMulDivInt32().
|
||||||
|
#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, 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
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T> class wxRescaleCoordWithValue;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
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<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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit wxRescaleCoordWithValue(T value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRescaleCoordWithFrom<T> From(wxSize oldScale)
|
||||||
|
{
|
||||||
|
return wxRescaleCoordWithFrom<T>(m_value, oldScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRescaleCoordWithFrom<T> From(int oldScaleX, int oldScaleY)
|
||||||
|
{
|
||||||
|
return From(wxSize(oldScaleX, oldScaleY));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wxPrivate::wxRescaleCoordWithValue<wxSize> wxRescaleCoord(int x, int y)
|
||||||
|
{
|
||||||
|
return wxPrivate::wxRescaleCoordWithValue<wxSize>(wxSize(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wxPrivate::wxRescaleCoordWithValue<wxPoint> wxRescaleCoord(wxPoint pt)
|
||||||
|
{
|
||||||
|
return wxPrivate::wxRescaleCoordWithValue<wxPoint>(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WX_PRIVATE_RESCALE_H_
|
@@ -3444,6 +3444,39 @@ public:
|
|||||||
Returns the new DPI.
|
Returns the new DPI.
|
||||||
*/
|
*/
|
||||||
wxSize GetNewDPI() const;
|
wxSize GetNewDPI() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Rescale a value in pixels to match the new DPI.
|
||||||
|
|
||||||
|
This is a convenience function to use in wxEVT_DPI_CHANGED event
|
||||||
|
handlers, as they often need to update some sizes to the new DPI.
|
||||||
|
It simply calls wxMulDivInt32() with new and old DPI values, but
|
||||||
|
is more readable and less error-prone.
|
||||||
|
|
||||||
|
For example, the returned value will be twice bigger than the original
|
||||||
|
one when switching from normal (96) DPI to high (2x, 192) DPI.
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
wxSize Scale(wxSize sz) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Rescale horizontal component to match the new DPI.
|
||||||
|
|
||||||
|
This is the same as Scale(), but for the horizontal component only.
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
int ScaleX(int x) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Rescale vertical component to match the new DPI.
|
||||||
|
|
||||||
|
This is the same as Scale(), but for the vertical component only.
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
int ScaleY(int y) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1344,4 +1344,3 @@ void wxDisplaySizeMM(int* width, int* height);
|
|||||||
*/
|
*/
|
||||||
wxSize wxGetDisplaySizeMM();
|
wxSize wxGetDisplaySizeMM();
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@@ -115,5 +115,15 @@ bool wxIsSameDouble(double x, double y);
|
|||||||
*/
|
*/
|
||||||
bool wxIsNullDouble(double x);
|
bool wxIsNullDouble(double x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the product of a number with a fraction with rounding.
|
||||||
|
|
||||||
|
This function returns @c n*numerator/denominator rounding the result. It is
|
||||||
|
similar to the standard Win32 @c MulDiv() function and, in fact, is
|
||||||
|
implemented by calling it under MSW, where @c wx/msw/wrapwin.h must be
|
||||||
|
included in addition to @c wx/math.h for it to be used.
|
||||||
|
*/
|
||||||
|
int wxMulDivInt32(int n, int numerator, int denominator);
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@@ -51,6 +51,10 @@
|
|||||||
wxDEFINE_SCOPED_PTR(wxEvent, wxEventPtr)
|
wxDEFINE_SCOPED_PTR(wxEvent, wxEventPtr)
|
||||||
#endif // wxUSE_BASE
|
#endif // wxUSE_BASE
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
#include "wx/private/rescale.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWin macros
|
// wxWin macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -933,6 +937,15 @@ wxHelpEvent::Origin wxHelpEvent::GuessOrigin(Origin origin)
|
|||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxDPIChangedEvent
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxSize wxDPIChangedEvent::Scale(wxSize sz) const
|
||||||
|
{
|
||||||
|
return wxRescaleCoord(sz).From(m_oldDPI).To(m_newDPI);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_GUI
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
|
|
||||||
|
@@ -74,12 +74,9 @@
|
|||||||
#include "wx/display.h"
|
#include "wx/display.h"
|
||||||
#include "wx/platinfo.h"
|
#include "wx/platinfo.h"
|
||||||
#include "wx/recguard.h"
|
#include "wx/recguard.h"
|
||||||
|
#include "wx/private/rescale.h"
|
||||||
#include "wx/private/window.h"
|
#include "wx/private/window.h"
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
#include "wx/msw/wrapwin.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Windows List
|
// Windows List
|
||||||
WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
|
WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
|
||||||
|
|
||||||
@@ -2905,12 +2902,9 @@ wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* w)
|
|||||||
{
|
{
|
||||||
const wxSize dpi = GetDPIHelper(w);
|
const wxSize dpi = GetDPIHelper(w);
|
||||||
|
|
||||||
const int baseline = wxDisplay::GetStdPPIValue();
|
const wxSize baseline = wxDisplay::GetStdPPI();
|
||||||
|
|
||||||
// Take care to not scale -1 because it has a special meaning of
|
return wxRescaleCoord(sz).From(baseline).To(dpi);
|
||||||
// "unspecified" which should be preserved.
|
|
||||||
return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, dpi.x, baseline),
|
|
||||||
sz.y == -1 ? -1 : wxMulDivInt32(sz.y, dpi.y, baseline));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -2919,12 +2913,9 @@ wxWindowBase::ToDIP(const wxSize& sz, const wxWindowBase* w)
|
|||||||
{
|
{
|
||||||
const wxSize dpi = GetDPIHelper(w);
|
const wxSize dpi = GetDPIHelper(w);
|
||||||
|
|
||||||
const int baseline = wxDisplay::GetStdPPIValue();
|
const wxSize baseline = wxDisplay::GetStdPPI();
|
||||||
|
|
||||||
// Take care to not scale -1 because it has a special meaning of
|
return wxRescaleCoord(sz).From(dpi).To(baseline);
|
||||||
// "unspecified" which should be preserved.
|
|
||||||
return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, baseline, dpi.x),
|
|
||||||
sz.y == -1 ? -1 : wxMulDivInt32(sz.y, baseline, dpi.y));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !wxHAVE_DPI_INDEPENDENT_PIXELS
|
#endif // !wxHAVE_DPI_INDEPENDENT_PIXELS
|
||||||
@@ -2963,28 +2954,14 @@ wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) const
|
|||||||
{
|
{
|
||||||
const wxSize base = GetDlgUnitBase();
|
const wxSize base = GetDlgUnitBase();
|
||||||
|
|
||||||
// NB: wxMulDivInt32() is used, because it correctly rounds the result
|
return wxRescaleCoord(pt).From(base).To(4, 8);
|
||||||
|
|
||||||
wxPoint pt2 = wxDefaultPosition;
|
|
||||||
if (pt.x != wxDefaultCoord)
|
|
||||||
pt2.x = wxMulDivInt32(pt.x, 4, base.x);
|
|
||||||
if (pt.y != wxDefaultCoord)
|
|
||||||
pt2.y = wxMulDivInt32(pt.y, 8, base.y);
|
|
||||||
|
|
||||||
return pt2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const
|
wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const
|
||||||
{
|
{
|
||||||
const wxSize base = GetDlgUnitBase();
|
const wxSize base = GetDlgUnitBase();
|
||||||
|
|
||||||
wxPoint pt2 = wxDefaultPosition;
|
return wxRescaleCoord(pt).From(4, 8).To(base);
|
||||||
if (pt.x != wxDefaultCoord)
|
|
||||||
pt2.x = wxMulDivInt32(pt.x, base.x, 4);
|
|
||||||
if (pt.y != wxDefaultCoord)
|
|
||||||
pt2.y = wxMulDivInt32(pt.y, base.y, 8);
|
|
||||||
|
|
||||||
return pt2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -5669,12 +5669,12 @@ void wxDataViewCtrl::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
{
|
{
|
||||||
int minWidth = m_cols[i]->GetMinWidth();
|
int minWidth = m_cols[i]->GetMinWidth();
|
||||||
if ( minWidth > 0 )
|
if ( minWidth > 0 )
|
||||||
minWidth = minWidth * event.GetNewDPI().x / event.GetOldDPI().x;
|
minWidth = event.ScaleX(minWidth);
|
||||||
m_cols[i]->SetMinWidth(minWidth);
|
m_cols[i]->SetMinWidth(minWidth);
|
||||||
|
|
||||||
int width = m_cols[i]->WXGetSpecifiedWidth();
|
int width = m_cols[i]->WXGetSpecifiedWidth();
|
||||||
if ( width > 0 )
|
if ( width > 0 )
|
||||||
width = width * event.GetNewDPI().x / event.GetOldDPI().x;
|
width = event.ScaleX(width);
|
||||||
m_cols[i]->SetWidth(width);
|
m_cols[i]->SetWidth(width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5781,7 +5781,7 @@ void wxGrid::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
if ( height <= 0 )
|
if ( height <= 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
height = height * event.GetNewDPI().x / event.GetOldDPI().x;
|
height = event.ScaleY(height);
|
||||||
total += height;
|
total += height;
|
||||||
|
|
||||||
m_rowHeights[i] = height;
|
m_rowHeights[i] = height;
|
||||||
@@ -5804,7 +5804,7 @@ void wxGrid::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
if ( width <= 0 )
|
if ( width <= 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
width = width * event.GetNewDPI().x / event.GetOldDPI().x;
|
width = event.ScaleX(width);
|
||||||
total += width;
|
total += width;
|
||||||
|
|
||||||
m_colWidths[i] = width;
|
m_colWidths[i] = width;
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include "wx/stockitem.h"
|
#include "wx/stockitem.h"
|
||||||
#include "wx/msw/private/button.h"
|
#include "wx/msw/private/button.h"
|
||||||
#include "wx/msw/private/dc.h"
|
#include "wx/msw/private/dc.h"
|
||||||
|
#include "wx/private/rescale.h"
|
||||||
#include "wx/private/window.h"
|
#include "wx/private/window.h"
|
||||||
|
|
||||||
#if wxUSE_MARKUP
|
#if wxUSE_MARKUP
|
||||||
@@ -185,11 +186,8 @@ wxSize wxButtonBase::GetDefaultSize(wxWindow* win)
|
|||||||
// character width metadata stored in the font; see
|
// character width metadata stored in the font; see
|
||||||
// http://support.microsoft.com/default.aspx/kb/145994 for detailed
|
// http://support.microsoft.com/default.aspx/kb/145994 for detailed
|
||||||
// discussion.
|
// discussion.
|
||||||
//
|
|
||||||
// NB: wxMulDivInt32() is used, because it correctly rounds the result
|
|
||||||
|
|
||||||
s_sizeBtn.SetAtNewDPI(wxSize(wxMulDivInt32(50, base.x, 4),
|
s_sizeBtn.SetAtNewDPI(wxRescaleCoord(50, 14).From(4, 8).To(base));
|
||||||
wxMulDivInt32(14, base.y, 8)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_sizeBtn.Get();
|
return s_sizeBtn.Get();
|
||||||
|
@@ -446,9 +446,10 @@ void wxListCtrl::OnDPIChanged(wxDPIChangedEvent &event)
|
|||||||
for ( int i = 0; i < numCols; ++i )
|
for ( int i = 0; i < numCols; ++i )
|
||||||
{
|
{
|
||||||
int width = GetColumnWidth(i);
|
int width = GetColumnWidth(i);
|
||||||
if ( width > 0 )
|
if ( width <= 0 )
|
||||||
width = width * event.GetNewDPI().x / event.GetOldDPI().x;
|
continue;
|
||||||
SetColumnWidth(i, width);
|
|
||||||
|
SetColumnWidth(i, event.ScaleX(width));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -653,11 +653,7 @@ void wxSlider::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
{
|
{
|
||||||
int thumbLen = GetThumbLength();
|
int thumbLen = GetThumbLength();
|
||||||
|
|
||||||
const double scaleFactor = (double)event.GetNewDPI().x / event.GetOldDPI().x;
|
SetThumbLength(event.ScaleX(thumbLen));
|
||||||
const double thumbLenScaled = thumbLen * scaleFactor;
|
|
||||||
thumbLen = (int)(scaleFactor > 1.0 ? ceil(thumbLenScaled) : floor(thumbLenScaled));
|
|
||||||
|
|
||||||
SetThumbLength(thumbLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -1949,8 +1949,6 @@ void wxToolBar::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
{
|
{
|
||||||
// Manually scale the size of the controls. Even though the font has been
|
// Manually scale the size of the controls. Even though the font has been
|
||||||
// updated, the internal size of the controls does not.
|
// updated, the internal size of the controls does not.
|
||||||
const float scaleFactor = (float)event.GetNewDPI().y / event.GetOldDPI().y;
|
|
||||||
|
|
||||||
wxToolBarToolsList::compatibility_iterator node;
|
wxToolBarToolsList::compatibility_iterator node;
|
||||||
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||||
{
|
{
|
||||||
@@ -1961,7 +1959,7 @@ void wxToolBar::OnDPIChanged(wxDPIChangedEvent& event)
|
|||||||
if ( wxControl* const control = tool->GetControl() )
|
if ( wxControl* const control = tool->GetControl() )
|
||||||
{
|
{
|
||||||
const wxSize oldSize = control->GetSize();
|
const wxSize oldSize = control->GetSize();
|
||||||
wxSize newSize = oldSize * scaleFactor;
|
wxSize newSize = event.Scale(oldSize);
|
||||||
|
|
||||||
// Use the best height for choice-based controls.
|
// Use the best height for choice-based controls.
|
||||||
// Scaling the current size does not work, because the control
|
// Scaling the current size does not work, because the control
|
||||||
|
@@ -82,6 +82,7 @@
|
|||||||
#include "wx/msw/dcclient.h"
|
#include "wx/msw/dcclient.h"
|
||||||
#include "wx/msw/seh.h"
|
#include "wx/msw/seh.h"
|
||||||
#include "wx/private/textmeasure.h"
|
#include "wx/private/textmeasure.h"
|
||||||
|
#include "wx/private/rescale.h"
|
||||||
|
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
#include "wx/tooltip.h"
|
#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
|
// Called from MSWUpdateonDPIChange() to recursively update the window
|
||||||
// sizer and any child sizers and spacers.
|
// 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 )
|
if ( !sizer )
|
||||||
{
|
{
|
||||||
@@ -4919,27 +4909,25 @@ static void UpdateSizerOnDPIChange(wxSizer* sizer, float scaleFactor)
|
|||||||
wxSizerItem* sizerItem = node->GetData();
|
wxSizerItem* sizerItem = node->GetData();
|
||||||
|
|
||||||
int border = sizerItem->GetBorder();
|
int border = sizerItem->GetBorder();
|
||||||
ScaleCoordIfSet(border, scaleFactor);
|
border = wxRescaleCoord(border).From(oldDPI).To(newDPI);
|
||||||
sizerItem->SetBorder(border);
|
sizerItem->SetBorder(border);
|
||||||
|
|
||||||
// only scale sizers and spacers, not windows
|
// only scale sizers and spacers, not windows
|
||||||
if ( sizerItem->IsSizer() || sizerItem->IsSpacer() )
|
if ( sizerItem->IsSizer() || sizerItem->IsSpacer() )
|
||||||
{
|
{
|
||||||
wxSize min = sizerItem->GetMinSize();
|
wxSize min = sizerItem->GetMinSize();
|
||||||
ScaleCoordIfSet(min.x, scaleFactor);
|
min = wxRescaleCoord(min).From(oldDPI).To(newDPI);
|
||||||
ScaleCoordIfSet(min.y, scaleFactor);
|
|
||||||
sizerItem->SetMinSize(min);
|
sizerItem->SetMinSize(min);
|
||||||
|
|
||||||
if ( sizerItem->IsSpacer() )
|
if ( sizerItem->IsSpacer() )
|
||||||
{
|
{
|
||||||
wxSize size = sizerItem->GetSize();
|
wxSize size = sizerItem->GetSize();
|
||||||
ScaleCoordIfSet(size.x, scaleFactor);
|
size = wxRescaleCoord(size).From(oldDPI).To(newDPI);
|
||||||
ScaleCoordIfSet(size.y, scaleFactor);
|
|
||||||
sizerItem->SetDimension(wxDefaultPosition, size);
|
sizerItem->SetDimension(wxDefaultPosition, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update any child sizers if this is a sizer
|
// 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)
|
wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
|
||||||
{
|
{
|
||||||
// update min and max size if necessary
|
// update min and max size if necessary
|
||||||
const float scaleFactor = (float)newDPI.y / oldDPI.y;
|
m_minHeight = wxRescaleCoord(m_minHeight).From(oldDPI).To(newDPI);
|
||||||
|
m_minWidth = wxRescaleCoord(m_minWidth).From(oldDPI).To(newDPI);
|
||||||
ScaleCoordIfSet(m_minHeight, scaleFactor);
|
m_maxHeight = wxRescaleCoord(m_maxHeight).From(oldDPI).To(newDPI);
|
||||||
ScaleCoordIfSet(m_minWidth, scaleFactor);
|
m_maxWidth = wxRescaleCoord(m_maxWidth).From(oldDPI).To(newDPI);
|
||||||
ScaleCoordIfSet(m_maxHeight, scaleFactor);
|
|
||||||
ScaleCoordIfSet(m_maxWidth, scaleFactor);
|
|
||||||
|
|
||||||
InvalidateBestSize();
|
InvalidateBestSize();
|
||||||
|
|
||||||
@@ -4961,7 +4947,7 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
|
|||||||
MSWUpdateFontOnDPIChange(newDPI);
|
MSWUpdateFontOnDPIChange(newDPI);
|
||||||
|
|
||||||
// update sizers
|
// update sizers
|
||||||
UpdateSizerOnDPIChange(GetSizer(), scaleFactor);
|
UpdateSizerOnDPIChange(GetSizer(), oldDPI, newDPI);
|
||||||
|
|
||||||
// update children
|
// update children
|
||||||
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
|
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
|
||||||
|
@@ -5441,7 +5441,7 @@ void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) {
|
|||||||
// adjust the margins to the new DPI
|
// adjust the margins to the new DPI
|
||||||
for ( int i = 0; i < SC_MAX_MARGIN; ++i )
|
for ( int i = 0; i < SC_MAX_MARGIN; ++i )
|
||||||
{
|
{
|
||||||
SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y));
|
SetMarginWidth(i, evt.ScaleY(GetMarginWidth(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide auto-complete popup, there is no (easy) way to set it to the correct size
|
// Hide auto-complete popup, there is no (easy) way to set it to the correct size
|
||||||
|
@@ -968,7 +968,7 @@ void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) {
|
|||||||
// adjust the margins to the new DPI
|
// adjust the margins to the new DPI
|
||||||
for ( int i = 0; i < SC_MAX_MARGIN; ++i )
|
for ( int i = 0; i < SC_MAX_MARGIN; ++i )
|
||||||
{
|
{
|
||||||
SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y));
|
SetMarginWidth(i, evt.ScaleY(GetMarginWidth(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide auto-complete popup, there is no (easy) way to set it to the correct size
|
// Hide auto-complete popup, there is no (easy) way to set it to the correct size
|
||||||
|
@@ -22,6 +22,11 @@
|
|||||||
#include "wx/tarstrm.h"
|
#include "wx/tarstrm.h"
|
||||||
#include "wx/zipstrm.h"
|
#include "wx/zipstrm.h"
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
// Needed for wxMulDivInt32().
|
||||||
|
#include "wx/msw/wrapwin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// test class
|
// test class
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -199,3 +204,12 @@ TEST_CASE("wxRound", "[math]")
|
|||||||
#endif
|
#endif
|
||||||
#endif // WXWIN_COMPATIBILITY_3_0
|
#endif // WXWIN_COMPATIBILITY_3_0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("wxMulDivInt32", "[math]")
|
||||||
|
{
|
||||||
|
// Check that it rounds correctly.
|
||||||
|
CHECK( wxMulDivInt32(15, 3, 2) == 23 );
|
||||||
|
|
||||||
|
// Check that it doesn't overflow.
|
||||||
|
CHECK( wxMulDivInt32((INT_MAX - 1)/2, 200, 100) == INT_MAX - 1 );
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user