Support DPI change in sizers

Return the size of DoGetDefaultBorderInPx as float, so no precision is lost
when multiplying it for DoubleBorder and TripleBorder.

Closes #18551.
This commit is contained in:
Maarten Bent
2019-11-01 21:07:15 +01:00
parent 349e73994b
commit 918e102533
4 changed files with 60 additions and 9 deletions

View File

@@ -106,6 +106,11 @@ public:
// default border size used by Border() below // default border size used by Border() below
static int GetDefaultBorder() static int GetDefaultBorder()
{
return wxRound(GetDefaultBorderFractional());
}
static float GetDefaultBorderFractional()
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
#ifdef __WXGTK20__ #ifdef __WXGTK20__
@@ -145,7 +150,7 @@ public:
wxSizerFlags& Border(int direction = wxALL) wxSizerFlags& Border(int direction = wxALL)
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
return Border(direction, GetDefaultBorder()); return Border(direction, wxRound(GetDefaultBorderFractional()));
#else #else
// no borders by default on limited size screen // no borders by default on limited size screen
wxUnusedVar(direction); wxUnusedVar(direction);
@@ -157,7 +162,7 @@ public:
wxSizerFlags& DoubleBorder(int direction = wxALL) wxSizerFlags& DoubleBorder(int direction = wxALL)
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
return Border(direction, 2*GetDefaultBorder()); return Border(direction, wxRound(2 * GetDefaultBorderFractional()));
#else #else
wxUnusedVar(direction); wxUnusedVar(direction);
@@ -168,7 +173,7 @@ public:
wxSizerFlags& TripleBorder(int direction = wxALL) wxSizerFlags& TripleBorder(int direction = wxALL)
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
return Border(direction, 3*GetDefaultBorder()); return Border(direction, wxRound(3 * GetDefaultBorderFractional()));
#else #else
wxUnusedVar(direction); wxUnusedVar(direction);
@@ -179,7 +184,7 @@ public:
wxSizerFlags& HorzBorder() wxSizerFlags& HorzBorder()
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
return Border(wxLEFT | wxRIGHT, GetDefaultBorder()); return Border(wxLEFT | wxRIGHT, wxRound(GetDefaultBorderFractional()));
#else #else
return *this; return *this;
#endif #endif
@@ -188,7 +193,7 @@ public:
wxSizerFlags& DoubleHorzBorder() wxSizerFlags& DoubleHorzBorder()
{ {
#if wxUSE_BORDER_BY_DEFAULT #if wxUSE_BORDER_BY_DEFAULT
return Border(wxLEFT | wxRIGHT, 2*GetDefaultBorder()); return Border(wxLEFT | wxRIGHT, wxRound(2 * GetDefaultBorderFractional()));
#else #else
return *this; return *this;
#endif #endif
@@ -223,7 +228,7 @@ public:
private: private:
#ifdef wxNEEDS_BORDER_IN_PX #ifdef wxNEEDS_BORDER_IN_PX
static int DoGetDefaultBorderInPx(); static float DoGetDefaultBorderInPx();
#endif // wxNEEDS_BORDER_IN_PX #endif // wxNEEDS_BORDER_IN_PX
int m_proportion; int m_proportion;

View File

@@ -1493,9 +1493,21 @@ public:
This value is scaled appropriately for the current DPI on the systems This value is scaled appropriately for the current DPI on the systems
where physical pixel values are used for the control positions and where physical pixel values are used for the control positions and
sizes, i.e. not with wxGTK or wxOSX. sizes, i.e. not with wxGTK or wxOSX.
@see GetDefaultBorderFractional()
*/ */
static int GetDefaultBorder(); static int GetDefaultBorder();
/**
Returns the border used by default, with fractional precision. For
example when the border is scaled to a non-integer DPI.
@see GetDefaultBorder()
@since 3.1.4
*/
static float GetDefaultBorderFractional();
/** /**
Aligns the object to the left, similar for @c Align(wxALIGN_LEFT). Aligns the object to the left, similar for @c Align(wxALIGN_LEFT).

View File

@@ -93,7 +93,7 @@ WX_DEFINE_EXPORTED_LIST( wxSizerItemList )
#ifdef wxNEEDS_BORDER_IN_PX #ifdef wxNEEDS_BORDER_IN_PX
/* static */ /* static */
int wxSizerFlags::DoGetDefaultBorderInPx() float wxSizerFlags::DoGetDefaultBorderInPx()
{ {
// Hard code 5px as it's the minimal border size between two controls, see // Hard code 5px as it's the minimal border size between two controls, see
// the table at the bottom of // the table at the bottom of
@@ -107,9 +107,12 @@ int wxSizerFlags::DoGetDefaultBorderInPx()
// as we don't have any associated window -- but, again, without changes // as we don't have any associated window -- but, again, without changes
// in the API, there is nothing we can do about this. // in the API, there is nothing we can do about this.
const wxWindow* const win = wxTheApp ? wxTheApp->GetTopWindow() : NULL; const wxWindow* const win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
static wxPrivate::DpiDependentValue<int> s_defaultBorderInPx; static wxPrivate::DpiDependentValue<float> s_defaultBorderInPx;
if ( s_defaultBorderInPx.HasChanged(win) ) if ( s_defaultBorderInPx.HasChanged(win) )
s_defaultBorderInPx.SetAtNewDPI(wxWindow::FromDIP(5, win)); {
s_defaultBorderInPx.SetAtNewDPI(
(float)(5 * (win ? win->GetContentScaleFactor() : 1)));
}
return s_defaultBorderInPx.Get(); return s_defaultBorderInPx.Get();
} }

View File

@@ -4884,6 +4884,37 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
// update font if necessary // update font if necessary
MSWUpdateFontOnDPIChange(newDPI); MSWUpdateFontOnDPIChange(newDPI);
// update sizers
if ( GetSizer() )
{
wxSizerItemList::compatibility_iterator current =
GetSizer()->GetChildren().GetFirst();
while ( current )
{
wxSizerItem* sizerItem = current->GetData();
int border = sizerItem->GetBorder();
ScaleCoordIfSet(border, scaleFactor);
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);
sizerItem->SetMinSize(min);
wxSize size = sizerItem->GetSize();
ScaleCoordIfSet(size.x, scaleFactor);
ScaleCoordIfSet(size.y, scaleFactor);
sizerItem->SetDimension(wxDefaultPosition, size);
}
current = current->GetNext();
}
}
// update children // update children
wxWindowList::compatibility_iterator current = GetChildren().GetFirst(); wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
while ( current ) while ( current )