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

View File

@@ -1493,9 +1493,21 @@ public:
This value is scaled appropriately for the current DPI on the systems
where physical pixel values are used for the control positions and
sizes, i.e. not with wxGTK or wxOSX.
@see GetDefaultBorderFractional()
*/
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).

View File

@@ -93,7 +93,7 @@ WX_DEFINE_EXPORTED_LIST( wxSizerItemList )
#ifdef wxNEEDS_BORDER_IN_PX
/* static */
int wxSizerFlags::DoGetDefaultBorderInPx()
float wxSizerFlags::DoGetDefaultBorderInPx()
{
// Hard code 5px as it's the minimal border size between two controls, see
// 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
// in the API, there is nothing we can do about this.
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) )
s_defaultBorderInPx.SetAtNewDPI(wxWindow::FromDIP(5, win));
{
s_defaultBorderInPx.SetAtNewDPI(
(float)(5 * (win ? win->GetContentScaleFactor() : 1)));
}
return s_defaultBorderInPx.Get();
}

View File

@@ -4884,6 +4884,37 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
// update font if necessary
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
wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
while ( current )