Merge branch 'per-monitor-dpi-aware-controls-1' of https://github.com/MaartenBent/wxWidgets

Update the font of some buddy controls when the DPI changes. Fix the
position of the statusbar after a DPI change. Add some changes that were
suggested in https://github.com/wxWidgets/wxWidgets/pull/1499 but left
out from it.

Some sizes are cached to improve the speed of the library. These sizes
become incorrect when the DPI changes. And are incorrect when a window
is created on a display with a different DPI. Fix this by checking if
the current DPI is the same as the DPI that was used when calculating
the size, otherwise recalculate the size.

Closes https://github.com/wxWidgets/wxWidgets/pull/1530
This commit is contained in:
Vadim Zeitlin
2019-09-07 14:53:26 +02:00
31 changed files with 241 additions and 137 deletions

View File

@@ -39,8 +39,9 @@ public:
// returns the old default item (possibly NULL)
virtual wxWindow *SetDefault();
// returns the default button size for this platform
static wxSize GetDefaultSize();
// returns the default button size for this platform, and optionally for a
// specific window when the platform supports per-monitor DPI
static wxSize GetDefaultSize(wxWindow* win = NULL);
protected:
wxDECLARE_NO_COPY_CLASS(wxButtonBase);

View File

@@ -34,6 +34,7 @@
#endif
class WXDLLIMPEXP_FWD_BASE wxArrayString;
class WXDLLIMPEXP_FWD_CORE wxWindow;
struct WXDLLIMPEXP_FWD_CORE wxNativeEncodingInfo;
#if defined(_WX_X_FONTLIKE)
@@ -118,11 +119,16 @@ public:
// set the XFLD
void SetXFontName(const wxString& xFontName);
#elif defined(__WXMSW__)
wxNativeFontInfo(const LOGFONT& lf_)
: lf(lf_),
pointSize(GetPointSizeAtPPI(lf.lfHeight))
{
}
// Preserve compatibility in the semi-public (i.e. private, but still
// unfortunately used by some existing code outside of the library) API
// by allowing to create wxNativeFontInfo from just LOGFONT, but ensure
// that we always specify the window, to use the correct DPI, when creating
// fonts inside the library itself.
wxNativeFontInfo(const LOGFONT& lf_, const wxWindow* win
#ifndef WXBUILDING
= NULL
#endif
);
// MSW-specific: get point size from LOGFONT height using specified DPI,
// or screen DPI when 0.

View File

@@ -162,6 +162,8 @@ protected:
virtual WXHRGN MSWGetRegionWithoutChildren() wxOVERRIDE;
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE;
// resolve ambiguity in base classes
virtual wxBorder GetDefaultBorder() const wxOVERRIDE { return wxRadioBoxBase::GetDefaultBorder(); }

View File

@@ -122,6 +122,9 @@ protected:
WXHBRUSH DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd) wxOVERRIDE;
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE;
void OnDPIChanged(wxDPIChangedEvent& event);
// the labels windows, if any
wxSubwindows *m_labels;

View File

@@ -72,6 +72,8 @@ protected:
// implementation of the public SetStatusWidths()
void MSWUpdateFieldsWidths();
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE;
// used by DoUpdateStatusText()
wxClientDC *m_pDC;

View File

@@ -11,6 +11,7 @@
#define _WX_PRIVATE_WINDOW_H_
#include "wx/gdicmn.h"
#include "wx/dynlib.h"
namespace wxPrivate
{
@@ -33,6 +34,67 @@ inline wxSize GetAverageASCIILetterSize(const T& of_what)
return s;
}
namespace
{
inline bool SupportsPerMonitorDPI()
{
static bool s_checkDPI =
#if defined(__WXMSW__) && wxUSE_DYNLIB_CLASS
// Only check the DPI when GetDpiForWindow is available because the old
// method (GetDeviceCaps) is a lot slower (about 1500 times).
// And when GetDpiForWindow is not available (for example older Windows
// versions), per-monitor DPI (V2) is also not available.
wxLoadedDLL("user32.dll").HasSymbol("GetDpiForWindow");
#else
false;
#endif
return s_checkDPI;
}
}
template <typename T>
class DpiDependentValue
{
public:
// Explicit initialization is needed if T is a primitive type.
DpiDependentValue()
: m_value(), m_dpi()
{ }
bool HasChanged(const wxWindowBase* win)
{
if ( win && SupportsPerMonitorDPI() )
{
const wxSize dpi = win->GetDPI();
if ( dpi != m_dpi )
{
m_dpi = dpi;
return true;
}
}
// Ensure that we return true the first time we're called,
// asuming that the value will always be set to a non-default value.
return m_value == T();
}
void SetAtNewDPI(const T& value)
{
m_value = value;
}
T& Get()
{
return m_value;
}
private:
T m_value;
wxSize m_dpi;
};
} // namespace wxPrivate
#endif // _WX_PRIVATE_WINDOW_H_

View File

@@ -120,13 +120,7 @@ public:
// current DPI, do it once (and cache the result) in another function.
#define wxNEEDS_BORDER_IN_PX
// We don't react to dynamic DPI changes, so we can cache the values of
// the border in on-screen pixels after computing it once. This
// could/should change in the future.
if ( !ms_defaultBorderInPx )
ms_defaultBorderInPx = DoGetDefaultBorderInPx();
return ms_defaultBorderInPx;
return DoGetDefaultBorderInPx();
#endif
#else
return 0;
@@ -230,8 +224,6 @@ public:
private:
#ifdef wxNEEDS_BORDER_IN_PX
static int DoGetDefaultBorderInPx();
static int ms_defaultBorderInPx;
#endif // wxNEEDS_BORDER_IN_PX
int m_proportion;

View File

@@ -179,11 +179,15 @@ public:
/**
Returns the default size for the buttons. It is advised to make all the dialog
buttons of the same size and this function allows retrieving the (platform and
current font dependent size) which should be the best suited for this.
Returns the default size for the buttons. It is advised to make all the
dialog buttons of the same size and this function allows retrieving the
(platform, and current font dependent) size which should be the best
suited for this.
The optional @a win argument is new since wxWidgets 3.1.3 and allows to
get a per-monitor DPI specific size.
*/
static wxSize GetDefaultSize();
static wxSize GetDefaultSize(wxWindow* win = NULL);
/**
Returns the string label for the button.

View File

@@ -3322,15 +3322,15 @@ public:
/**
@class wxDPIChangedEvent
Event sent when the resolution (measured in dots-per-inch, or DPI) of the
monitor a window is on changes.
Event sent when the display scale factor or pixel density (measured in
dots-per-inch, or DPI) of the monitor a window is on changes.
The event is sent to each wxTopLevelWindow affected by the change, and all
its children recursively. For example, this event is sent to the window
when it is moved, by the user, from a display using some DPI value to
another display using a different DPI value. It also sent to all program
windows on the given display if its DPI changes due to a change in the
system settings.
its children recursively (post-order traversal). For example, this event is
sent to the window when it is moved, by the user, from a display using some
DPI value to another display using a different DPI value. It also sent to
all program windows on the given display if its DPI changes due to a change
in the system settings.
Currently this event is generated by wxMSW port if only and only if the
MSW application runs under Windows 10 Creators Update (v1703) or later and
@@ -3359,15 +3359,11 @@ class wxDPIChangedEvent : public wxEvent
public:
/**
Returns the old DPI.
@since 3.1.3
*/
wxSize GetOldDPI() const;
/**
Returns the new DPI.
@since 3.1.3
*/
wxSize GetNewDPI() const;
};

View File

@@ -28,11 +28,13 @@
#include "wx/button.h"
#include "wx/statbox.h"
#include "wx/toplevel.h"
#include "wx/app.h"
#endif // WX_PRECOMP
#include "wx/display.h"
#include "wx/vector.h"
#include "wx/listimpl.cpp"
#include "wx/private/window.h"
//---------------------------------------------------------------------------
@@ -90,8 +92,6 @@ WX_DEFINE_EXPORTED_LIST( wxSizerItemList )
#ifdef wxNEEDS_BORDER_IN_PX
int wxSizerFlags::ms_defaultBorderInPx = 0;
/* static */
int wxSizerFlags::DoGetDefaultBorderInPx()
{
@@ -103,11 +103,14 @@ int wxSizerFlags::DoGetDefaultBorderInPx()
// between related and unrelated controls, as explained at the above URL,
// but we don't have a way to specify this in our API currently.
//
// We also have to use the DPI for the primary monitor here as we don't
// have any associated window, so this is wrong on systems using multiple
// monitors with different resolutions too -- but, again, without changes
// We also have to use the DPI for the monitor showing the top window here
// as we don't have any associated window -- but, again, without changes
// in the API, there is nothing we can do about this.
return wxWindow::FromDIP(5, NULL);
const wxWindow* const win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
static wxPrivate::DpiDependentValue<int> s_defaultBorderInPx;
if ( s_defaultBorderInPx.HasChanged(win) )
s_defaultBorderInPx.SetAtNewDPI(wxWindow::FromDIP(5, win));
return s_defaultBorderInPx.Get();
}
#endif // wxNEEDS_BORDER_IN_PX

View File

@@ -2921,7 +2921,7 @@ wxWindowBase::ToDIP(const wxSize& sz, const wxWindowBase* w)
// using them.
wxSize wxWindowBase::GetDlgUnitBase() const
{
const wxWindowBase * const parent = wxGetTopLevelParent((wxWindow*)this);
const wxWindowBase* const parent = wxGetTopLevelParent((wxWindow*)this);
wxCHECK_MSG( parent, wxDefaultSize, wxS("Must have TLW parent") );
@@ -2929,10 +2929,10 @@ wxSize wxWindowBase::GetDlgUnitBase() const
{
// Default GUI font is used. This is the most common case, so
// cache the results.
static wxSize s_defFontSize;
if ( s_defFontSize.x == 0 )
s_defFontSize = wxPrivate::GetAverageASCIILetterSize(*parent);
return s_defFontSize;
static wxPrivate::DpiDependentValue<wxSize> s_defFontSize;
if ( s_defFontSize.HasChanged(parent) )
s_defFontSize.SetAtNewDPI(wxPrivate::GetAverageASCIILetterSize(*parent));
return s_defFontSize.Get();
}
else
{

View File

@@ -165,7 +165,7 @@ wxWindow *wxButton::SetDefault()
}
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* WXUNUSED(win))
{
static wxSize size = wxDefaultSize;
if (size == wxDefaultSize)

View File

@@ -166,7 +166,7 @@ wxWindow *wxButton::SetDefault()
}
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* WXUNUSED(win))
{
return wxSize(80,26);
}

View File

@@ -160,14 +160,25 @@ WXDWORD wxButton::MSWGetStyle(long style, WXDWORD *exstyle) const
}
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* win)
{
static wxSize s_sizeBtn;
static wxPrivate::DpiDependentValue<wxSize> s_sizeBtn;
if ( s_sizeBtn.x == 0 )
if ( s_sizeBtn.HasChanged(win) )
{
wxSize base;
if ( win )
{
wxClientDC dc(win);
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
base = wxPrivate::GetAverageASCIILetterSize(dc);
}
else
{
wxScreenDC dc;
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
base = wxPrivate::GetAverageASCIILetterSize(dc);
}
// The size of a standard button in the dialog units is 50x14,
// translate this to pixels.
@@ -180,12 +191,11 @@ wxSize wxButtonBase::GetDefaultSize()
//
// NB: wxMulDivInt32() is used, because it correctly rounds the result
const wxSize base = wxPrivate::GetAverageASCIILetterSize(dc);
s_sizeBtn.x = wxMulDivInt32(50, base.x, 4);
s_sizeBtn.y = wxMulDivInt32(14, base.y, 8);
s_sizeBtn.SetAtNewDPI(wxSize(wxMulDivInt32(50, base.x, 4),
wxMulDivInt32(14, base.y, 8)));
}
return s_sizeBtn;
return s_sizeBtn.Get();
}
// ----------------------------------------------------------------------------

View File

@@ -28,15 +28,14 @@
#include "wx/checkbox.h"
#ifndef WX_PRECOMP
#include "wx/brush.h"
#include "wx/dcclient.h"
#include "wx/dcscreen.h"
#include "wx/settings.h"
#endif
#include "wx/renderer.h"
#include "wx/msw/uxtheme.h"
#include "wx/msw/private/button.h"
#include "wx/private/window.h"
#include "wx/msw/missing.h"
// ============================================================================
@@ -98,16 +97,17 @@ WXDWORD wxCheckBox::MSWGetStyle(long style, WXDWORD *exstyle) const
wxSize wxCheckBox::DoGetBestClientSize() const
{
static int s_checkSize = 0;
static wxPrivate::DpiDependentValue<wxCoord> s_checkSize;
if ( !s_checkSize )
if ( s_checkSize.HasChanged(this) )
{
wxScreenDC dc;
wxClientDC dc(const_cast<wxCheckBox*>(this));
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
s_checkSize = dc.GetCharHeight();
s_checkSize.SetAtNewDPI(dc.GetCharHeight());
}
wxCoord& checkSize = s_checkSize.Get();
wxString str = wxGetWindowText(GetHWND());
int wCheckbox, hCheckbox;
@@ -116,7 +116,7 @@ wxSize wxCheckBox::DoGetBestClientSize() const
wxClientDC dc(const_cast<wxCheckBox *>(this));
dc.SetFont(GetFont());
dc.GetMultiLineTextExtent(GetLabelText(str), &wCheckbox, &hCheckbox);
wCheckbox += s_checkSize + GetCharWidth();
wCheckbox += checkSize + GetCharWidth();
if ( ::GetWindowLong(GetHwnd(), GWL_STYLE) & BS_MULTILINE )
{
@@ -128,16 +128,16 @@ wxSize wxCheckBox::DoGetBestClientSize() const
// label appears on 3 lines, not 2, under Windows 2003 using
// classic look and feel (although it works fine under Windows 7,
// with or without themes).
wCheckbox += s_checkSize;
wCheckbox += checkSize;
}
if ( hCheckbox < s_checkSize )
hCheckbox = s_checkSize;
if ( hCheckbox < checkSize )
hCheckbox = checkSize;
}
else
{
wCheckbox = s_checkSize;
hCheckbox = s_checkSize;
wCheckbox = checkSize;
hCheckbox = checkSize;
}
return wxSize(wCheckbox, hCheckbox);

View File

@@ -63,9 +63,6 @@ public:
private:
bool m_destroyCursor;
// standard cursor size, computed on first use
static wxSize ms_sizeStd;
};
// ----------------------------------------------------------------------------
@@ -110,28 +107,17 @@ public:
// wxCursorRefData
// ----------------------------------------------------------------------------
wxSize wxCursorRefData::ms_sizeStd;
wxCoord wxCursorRefData::GetStandardWidth()
{
if ( !ms_sizeStd.x )
{
wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
ms_sizeStd.x = wxSystemSettings::GetMetric(wxSYS_CURSOR_X, win);
}
return ms_sizeStd.x;
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
return wxSystemSettings::GetMetric(wxSYS_CURSOR_X, win);
}
wxCoord wxCursorRefData::GetStandardHeight()
{
if ( !ms_sizeStd.y )
{
wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
ms_sizeStd.y = wxSystemSettings::GetMetric(wxSYS_CURSOR_Y, win);
}
return ms_sizeStd.y;
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
return wxSystemSettings::GetMetric(wxSYS_CURSOR_Y, win);
}
wxCursorRefData::wxCursorRefData(HCURSOR hcursor, bool destroy)

View File

@@ -403,6 +403,11 @@ void wxFontRefData::Free()
// wxNativeFontInfo
// ----------------------------------------------------------------------------
wxNativeFontInfo::wxNativeFontInfo(const LOGFONT& lf_, const wxWindow* win)
: lf(lf_),
pointSize(GetPointSizeAtPPI(lf.lfHeight, win ? win->GetDPI().y : 0))
{ }
/* static */
float wxNativeFontInfo::GetPointSizeAtPPI(int lfHeight, int ppi)
{

View File

@@ -152,7 +152,7 @@ int wxFontDialog::ShowModal()
if ( ChooseFont(&chooseFontStruct) != 0 )
{
wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors);
m_fontData.m_chosenFont = wxFont(wxNativeFontInfo(logFont));
m_fontData.m_chosenFont = wxFont(wxNativeFontInfo(logFont, this));
m_fontData.EncodingInfo().facename = logFont.lfFaceName;
m_fontData.EncodingInfo().charset = logFont.lfCharSet;

View File

@@ -278,7 +278,7 @@ void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
{
return wxFont(wxNativeFontInfo(*logFont));
return wxFont(wxNativeFontInfo(*logFont, NULL));
}
#endif // WXWIN_COMPATIBILITY_3_0

View File

@@ -335,6 +335,14 @@ void wxFrame::PositionStatusBar()
//else: no adjustments necessary for the toolbar on top
#endif // wxUSE_TOOLBAR
// GetSize returns the height of the clientSize in which the statusbar
// height is subtracted (see wxFrame::DoGetClientSize). When the DPI of the
// window changes, the statusbar height will likely change so we need to
// account for this difference. If not, the statusbar will be positioned
// too high or low.
int shOld;
m_frameStatusBar->GetSize(NULL, &shOld);
// Resize the status bar to its default height, as it could have been set
// to a wrong value before by WM_SIZE sent during the frame creation and
// our status bars preserve their programmatically set size to avoid being
@@ -342,8 +350,9 @@ void wxFrame::PositionStatusBar()
// this here, the status bar would retain the possibly wrong current height.
m_frameStatusBar->SetSize(x, h, w, wxDefaultCoord, wxSIZE_AUTO_HEIGHT);
int sw, sh;
m_frameStatusBar->GetSize(&sw, &sh);
int sh;
m_frameStatusBar->GetSize(NULL, &sh);
h += shOld - sh;
// Since we wish the status bar to be directly under the client area,
// we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.

View File

@@ -348,7 +348,7 @@ void MenuDrawData::Init()
wxUxThemeFont themeFont;
::GetThemeSysFont(hTheme, TMT_MENUFONT, themeFont.GetPtr());
Font = wxFont(themeFont.GetLOGFONT());
Font = wxFont(wxNativeFontInfo(themeFont.GetLOGFONT(), window));
Theme = true;
@@ -392,15 +392,7 @@ void MenuDrawData::Init()
Offset = -12;
wxNativeFontInfo info(metrics.lfMenuFont);
// wxNativeFontInfo constructor calculates the pointSize using the
// main screen DPI. But lfHeight is based on the window DPI.
if ( window )
{
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
info.lf.lfHeight, window->GetDPI().y);
}
Font = wxFont(info);
Font = wxFont(wxNativeFontInfo(metrics.lfMenuFont, window));
Theme = false;
}

View File

@@ -397,15 +397,8 @@ void wxMessageDialog::AdjustButtonLabels()
wxFont wxMessageDialog::GetMessageFont()
{
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
wxNativeFontInfo info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont);
// wxNativeFontInfo constructor calculates the pointSize using the
// main screen DPI. But lfHeight is based on the window DPI.
if ( win )
{
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
info.lf.lfHeight, win->GetDPI().y);
}
const wxNativeFontInfo
info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont, win);
return info;
}

View File

@@ -751,6 +751,14 @@ int wxRadioBox::GetItemFromPoint(const wxPoint& pt) const
return wxNOT_FOUND;
}
void wxRadioBox::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
{
wxStaticBox::MSWUpdateFontOnDPIChange(newDPI);
if ( m_font.IsOk() )
m_radioButtons->SetFont(m_font);
}
// ----------------------------------------------------------------------------
// radio box drawing
// ----------------------------------------------------------------------------

View File

@@ -29,11 +29,11 @@
#ifndef WX_PRECOMP
#include "wx/settings.h"
#include "wx/dcscreen.h"
#include "wx/toplevel.h"
#include "wx/dcclient.h"
#endif
#include "wx/msw/private.h"
#include "wx/private/window.h"
#include "wx/renderer.h"
#include "wx/msw/uxtheme.h"
@@ -238,31 +238,32 @@ bool wxRadioButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
wxSize wxRadioButton::DoGetBestSize() const
{
static int s_radioSize = 0;
static wxPrivate::DpiDependentValue<wxCoord> s_radioSize;
if ( !s_radioSize )
if ( s_radioSize.HasChanged(this) )
{
wxScreenDC dc;
wxClientDC dc(const_cast<wxRadioButton*>(this));
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
s_radioSize = dc.GetCharHeight();
s_radioSize.SetAtNewDPI(dc.GetCharHeight());
}
wxCoord& radioSize = s_radioSize.Get();
wxString str = GetLabel();
int wRadio, hRadio;
if ( !str.empty() )
{
GetTextExtent(GetLabelText(str), &wRadio, &hRadio);
wRadio += s_radioSize + GetCharWidth();
wRadio += radioSize + GetCharWidth();
if ( hRadio < s_radioSize )
hRadio = s_radioSize;
if ( hRadio < radioSize )
hRadio = radioSize;
}
else
{
wRadio = s_radioSize;
hRadio = s_radioSize;
wRadio = radioSize;
hRadio = radioSize;
}
return wxSize(wRadio, hRadio);

View File

@@ -150,7 +150,7 @@ wxFont wxCreateFontFromStockObject(int index)
LOGFONT lf;
if ( ::GetObject(hFont, sizeof(LOGFONT), &lf) != 0 )
{
wxNativeFontInfo info(lf);
wxNativeFontInfo info(lf, NULL);
font.Create(info);
}
else
@@ -183,16 +183,8 @@ wxFont wxSystemSettingsNative::GetFont(wxSystemFont index)
// controls may prefer to use lfStatusFont or lfCaptionFont if it
// is more appropriate for them
const wxWindow* win = wxTheApp ? wxTheApp->GetTopWindow() : NULL;
wxNativeFontInfo
info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont);
// wxNativeFontInfo constructor calculates the pointSize using the
// main screen DPI. But lfHeight is based on the window DPI.
if ( win )
{
info.pointSize = wxNativeFontInfo::GetPointSizeAtPPI(
info.lf.lfHeight, win->GetDPI().y);
}
const wxNativeFontInfo
info(wxMSWImpl::GetNonClientMetrics(win).lfMessageFont, win);
gs_fontDefault = new wxFont(info);
}
@@ -358,7 +350,7 @@ extern wxFont wxGetCCDefaultFont()
win
) )
{
return wxFont(lf);
return wxFont(wxNativeFontInfo(lf, win));
}
else
{

View File

@@ -163,13 +163,17 @@ bool wxSlider::Create(wxWindow *parent,
m_labels->Set(n, wnd, lblid);
}
m_labels->SetFont(GetFont());
}
// now create the main control too
if ( !MSWCreateControl(TRACKBAR_CLASS, wxEmptyString, pos, size) )
return false;
if ( m_labels )
{
m_labels->SetFont(GetFont());
}
// and initialize everything
SetRange(minValue, maxValue);
SetValue(value);
@@ -183,6 +187,8 @@ bool wxSlider::Create(wxWindow *parent,
SetSize(size);
}
Bind(wxEVT_DPI_CHANGED, &wxSlider::OnDPIChanged, this);
return true;
}
@@ -541,7 +547,7 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
wxSize wxSlider::DoGetBestSize() const
{
// this value is arbitrary:
static const int length = FromDIP(100);
const int length = FromDIP(100);
const int thumbSize = GetThumbLength();
const int tickSize = FromDIP(TICK);
@@ -619,6 +625,27 @@ WXHBRUSH wxSlider::DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd)
return hBrush;
}
void wxSlider::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
{
wxSliderBase::MSWUpdateFontOnDPIChange(newDPI);
if ( m_labels && m_font.IsOk() )
{
m_labels->SetFont(m_font);
}
}
void wxSlider::OnDPIChanged(wxDPIChangedEvent& event)
{
int thumbLen = GetThumbLength();
const double scaleFactor = (double)event.GetNewDPI().x / event.GetOldDPI().x;
const double thumbLenScaled = thumbLen * scaleFactor;
thumbLen = (int)(scaleFactor > 1.0 ? ceil(thumbLenScaled) : floor(thumbLenScaled));
SetThumbLength(thumbLen);
}
// ----------------------------------------------------------------------------
// slider-specific methods
// ----------------------------------------------------------------------------

View File

@@ -166,7 +166,8 @@ bool wxStatusBar::SetFont(const wxFont& font)
if (!wxWindow::SetFont(font))
return false;
if (m_pDC) m_pDC->SetFont(font);
if ( m_pDC )
m_pDC->SetFont(m_font);
return true;
}
@@ -256,6 +257,14 @@ void wxStatusBar::MSWUpdateFieldsWidths()
delete [] pWidths;
}
void wxStatusBar::MSWUpdateFontOnDPIChange(const wxSize& newDPI)
{
wxStatusBarBase::MSWUpdateFontOnDPIChange(newDPI);
if ( m_pDC && m_font.IsOk() )
m_pDC->SetFont(m_font);
}
void wxStatusBar::DoUpdateStatusText(int nField)
{
if (!m_pDC)

View File

@@ -3207,7 +3207,8 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
// CHARFORMAT stores it to pixel-based units used by LOGFONT.
// Note that RichEdit seems to always use standard DPI of 96, even when the
// window is a monitor using a higher DPI.
lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f, 96);
lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f,
GetDPI().y);
lf.lfWidth = 0;
lf.lfCharSet = ANSI_CHARSET; // FIXME: how to get correct charset?
lf.lfClipPrecision = 0;
@@ -3240,7 +3241,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
else
lf.lfWeight = FW_NORMAL;
wxFont font(lf);
wxFont font(wxNativeFontInfo(lf, this));
if (font.IsOk())
{
style.SetFont(font);

View File

@@ -137,7 +137,7 @@ bool wxButton::OSXHandleClicked( double WXUNUSED(timestampsec) )
}
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* WXUNUSED(win))
{
return wxAnyButton::GetDefaultSize();
}

View File

@@ -61,7 +61,7 @@ wxWindow *wxButton::SetDefault()
}
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* WXUNUSED(win))
{
static wxSize size = wxDefaultSize;
if (size == wxDefaultSize)

View File

@@ -110,7 +110,7 @@ wxButton::~wxButton()
// ----------------------------------------------------------------------------
/* static */
wxSize wxButtonBase::GetDefaultSize()
wxSize wxButtonBase::GetDefaultSize(wxWindow* WXUNUSED(win))
{
static wxSize s_sizeBtn;