Merge branch 'art-scalefactor'

Fix confusion between different kinds of coordinates in wxAUI code,
restoring correct behaviour in high DPI on all platforms.

See #2620.

Closes #19331.
This commit is contained in:
Vadim Zeitlin
2022-01-13 17:51:00 +00:00
26 changed files with 294 additions and 114 deletions

View File

@@ -167,15 +167,19 @@ Currently the following symbols exist:
have an efficient (CPU-specific) implementation. Notice that the functions
themselves are always available but can be prohibitively slow to use when
implemented in a generic way, using a critical section.}
@itemdef{wxHAS_BITMAP_SCALE_FACTOR, Defined in @c wx/bitmap.h if bitmaps
actually use scale factor under the current platform, see
wxBitmap::SetScaleFactor().}
@itemdef{wxHAS_BITMAPTOGGLEBUTTON, Defined in @c wx/tglbtn.h if
wxBitmapToggleButton class is available in addition to wxToggleButton.}
@itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler
supports template Read() and Write() methods in wxConfig.}
@itemdef{wxHAS_DEPRECATED_ATTR, Defined if C++14 @c [[deprecated]] attribute is
supported (this symbol only exists in wxWidgets 3.1.6 or later).}
@itemdef{wxHAS_DPI_INDEPENDENT_PIXELS, Defined if pixel coordinates on the
current platform scale with DPI, i.e. if the given length in pixels has the
same apparent size on the display independently of the DPI (this symbol
only exists in wxWidgets 3.1.6 or later). Note that it should rarely, if
ever, be necessary to use this symbol directly, functions such as
wxWindow::FromDIP() and wxBitmap::GetScaledSize() exist to hide the
differences between the platforms with and without DPI-independent pixels.}
@itemdef{wxHAS_MEMBER_DEFAULT, Defined if the currently used compiler supports
C++11 @c =default.}
@itemdef{wxHAS_LARGE_FILES, Defined if wxFile supports files more than 4GB in

View File

@@ -234,14 +234,11 @@ protected:
return wxNullBitmap;
}
// Derived classes must override CreateBitmapBundle if they provide
// a bundle that cannot be represented through an ordinary bitmap.
// Default implementation creates a wxBitmapBundle which returns the
// specified art resource in whichever size it is being asked for.
virtual wxBitmapBundle CreateBitmapBundle(const wxArtID& id,
const wxArtClient& client,
const wxSize& size)
{
return wxBitmapBundle(CreateBitmap(id, client, size));
}
const wxSize& size);
virtual wxIconBundle CreateIconBundle(const wxArtID& WXUNUSED(id),
const wxArtClient& WXUNUSED(client))

View File

@@ -186,12 +186,22 @@ public:
wxSize GetSize() const
{ return wxSize(GetWidth(), GetHeight()); }
// support for scaled bitmaps
// Store or return the scale factor, which determines the ratio between the
// bitmap physical size and its DIP size (on all platforms). By default
// it's just 1.
virtual void SetScaleFactor(double scale);
virtual double GetScaleFactor() const;
virtual double GetScaledWidth() const;
virtual double GetScaledHeight() const;
virtual wxSize GetScaledSize() const;
// This function returns the size divided by the scale factor, so that a
// 64x64 bitmap with a scale factor of 2 has DIP size of 32x32 everywhere.
wxSize GetDIPSize() const;
// These functions return the corresponding metrics divided by the scale
// factor on platforms with DPI-independent pixels (e.g. GTK, Mac) and just
// the same thing as the non-scaled accessors elsewhere (e.g. MSW).
double GetScaledWidth() const;
double GetScaledHeight() const;
wxSize GetScaledSize() const;
#if wxUSE_IMAGE
virtual wxImage ConvertToImage() const = 0;

View File

@@ -111,5 +111,20 @@
// compiler, so this symbol exists purely for compatibility.
#define wxHAS_EVENT_BIND
/*
Some platforms use DPI-independent pixels, i.e. pixels actually scale with
DPI and a 100px-wide window has the same apparent size on the display in
normal and high (i.e. 2x, or 200% scaling) DPI, while others always use
physical pixels and a window must be 200px wide to have the same apparent
size in high DPI as in normal DPI.
*/
#if defined(__WXGTK3__) || defined(__WXMAC__)
#define wxHAS_DPI_INDEPENDENT_PIXELS
// This is an older synonym kept only for compatibility
#define wxHAVE_DPI_INDEPENDENT_PIXELS
#endif
#endif /* _WX_FEATURES_H_ */

View File

@@ -17,10 +17,6 @@ typedef struct _GdkPixbuf GdkPixbuf;
class WXDLLIMPEXP_FWD_CORE wxPixelDataBase;
class WXDLLIMPEXP_FWD_CORE wxCursor;
#ifdef __WXGTK3__
#define wxHAS_BITMAP_SCALE_FACTOR
#endif
//-----------------------------------------------------------------------------
// wxMask
//-----------------------------------------------------------------------------
@@ -89,7 +85,7 @@ public:
{ return Create(sz.GetWidth(), sz.GetHeight(), depth); }
bool Create(int width, int height, const wxDC& WXUNUSED(dc))
{ return Create(width,height); }
#ifdef wxHAS_BITMAP_SCALE_FACTOR
#ifdef __WXGTK3__
virtual bool CreateScaled(int w, int h, int depth, double scale) wxOVERRIDE;
virtual void SetScaleFactor(double scale) wxOVERRIDE;
virtual double GetScaleFactor() const wxOVERRIDE;

View File

@@ -184,12 +184,18 @@ public:
void UseAlpha(bool use = true);
void ResetAlpha() { UseAlpha(false); }
// provide stabs of scaled bitmaps functions, they are trivial here
// allow setting and storing the scale factor
virtual void SetScaleFactor(double scale);
virtual double GetScaleFactor() const;
virtual double GetScaledWidth() const;
virtual double GetScaledHeight() const;
virtual wxSize GetScaledSize() const;
// return the size divided by scale factor
wxSize GetDIPSize() const;
// but scaled metrics accessors return the same thing as non-scaled ones,
// just as in all the other ports without wxHAS_DPI_INDEPENDENT_PIXELS.
double GetScaledWidth() const;
double GetScaledHeight() const;
wxSize GetScaledSize() const;
// implementation only from now on
// -------------------------------

View File

@@ -36,6 +36,8 @@ public:
{
m_width = m_height = m_depth = 0;
m_scaleFactor = 1.0;
m_handle = NULL;
}
@@ -45,6 +47,8 @@ public:
m_height = data.m_height;
m_depth = data.m_depth;
m_scaleFactor = data.m_scaleFactor;
// can't copy handles like this, derived class copy ctor must do it!
m_handle = NULL;
}
@@ -65,6 +69,9 @@ public:
// the depth of the image
int m_depth;
// scale factor of the image
double m_scaleFactor;
// the handle to it
union
{
@@ -111,6 +118,10 @@ public:
int GetWidth() const { return IsNull() ? 0 : GetGDIImageData()->m_width; }
int GetHeight() const { return IsNull() ? 0 : GetGDIImageData()->m_height; }
int GetDepth() const { return IsNull() ? 0 : GetGDIImageData()->m_depth; }
double GetScaleFactor() const
{
return IsNull() ? 1.0 : GetGDIImageData()->m_scaleFactor;
}
wxSize GetSize() const
{

View File

@@ -71,7 +71,7 @@ public:
#endif // WXWIN_COMPATIBILITY_3_0
WXHICON GetHICON() const { return (WXHICON)GetHandle(); }
bool InitFromHICON(WXHICON icon, int width, int height);
bool InitFromHICON(WXHICON icon, int width, int height, double scale = 1.0);
// create from bitmap (which should have a mask unless it's monochrome):
// there shouldn't be any implicit bitmap -> icon conversion (i.e. no

View File

@@ -13,8 +13,6 @@
#include "wx/palette.h"
#define wxHAS_BITMAP_SCALE_FACTOR
// Bitmap
class WXDLLIMPEXP_FWD_CORE wxBitmap;
class wxBitmapRefData ;

View File

@@ -49,10 +49,6 @@
#define wxUSE_MENUS_NATIVE wxUSE_MENUS
#endif // __WXUNIVERSAL__/!__WXUNIVERSAL__
#if defined(__WXGTK3__) || defined(__WXMAC__)
#define wxHAVE_DPI_INDEPENDENT_PIXELS
#endif
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
@@ -542,7 +538,7 @@ public:
// Return the magnification of the content of this window for the platforms
// using logical pixels different from physical ones, i.e. those for which
// wxHAVE_DPI_INDEPENDENT_PIXELS is defined. For the other ones, always
// wxHAS_DPI_INDEPENDENT_PIXELS is defined. For the other ones, always
// returns 1, regardless of DPI scale factor returned by the function below.
virtual double GetContentScaleFactor() const;
@@ -997,14 +993,14 @@ public:
// horizontal and vertical directions, but this could, in principle,
// change too, so prefer using the overloads taking wxPoint or wxSize.
#ifdef wxHAVE_DPI_INDEPENDENT_PIXELS
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
static wxSize FromDIP(const wxSize& sz, const wxWindowBase* WXUNUSED(w))
{
return sz;
}
#else
static wxSize FromDIP(const wxSize& sz, const wxWindowBase* w);
#endif // wxHAVE_DPI_INDEPENDENT_PIXELS
#endif // wxHAS_DPI_INDEPENDENT_PIXELS
static wxPoint FromDIP(const wxPoint& pt, const wxWindowBase* w)
{
const wxSize sz = FromDIP(wxSize(pt.x, pt.y), w);
@@ -1019,14 +1015,14 @@ public:
wxPoint FromDIP(const wxPoint& pt) const { return FromDIP(pt, this); }
int FromDIP(int d) const { return FromDIP(d, this); }
#ifdef wxHAVE_DPI_INDEPENDENT_PIXELS
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
static wxSize ToDIP(const wxSize& sz, const wxWindowBase* WXUNUSED(w))
{
return sz;
}
#else
static wxSize ToDIP(const wxSize& sz, const wxWindowBase* w);
#endif // wxHAVE_DPI_INDEPENDENT_PIXELS
#endif // wxHAS_DPI_INDEPENDENT_PIXELS
static wxPoint ToDIP(const wxPoint& pt, const wxWindowBase* w)
{
const wxSize sz = ToDIP(wxSize(pt.x, pt.y), w);

View File

@@ -307,7 +307,9 @@ public:
@param client
wxArtClient identifier of the client (i.e. who is asking for the bitmap).
@param size
Default size for the returned bundle.
Default size for the returned bundle, i.e. the size of the bitmap
in normal DPI (this implies that wxWindow::FromDIP() must @e not be
used with it).
@return If any of the registered providers recognizes the ID in its
CreateBitmapBundle(), this bundle is returned. Otherwise, if any of

View File

@@ -541,6 +541,22 @@ public:
*/
virtual int GetDepth() const;
/**
Returns the size of bitmap in DPI-independent units.
This assumes that the bitmap was created using the value of scale
factor corresponding to the current DPI (see CreateScaled() and
SetScaleFactor()) and returns its physical size divided by this scale
factor.
Unlike GetScaledSize(), this function returns the same value under all
platforms and so its result should @e not be used as window or device
context coordinates.
@since 3.1.6
*/
wxSize GetDIPSize() const;
/**
Returns the static list of bitmap format handlers.
@@ -604,23 +620,29 @@ public:
@since 2.9.5
*/
virtual double GetScaledHeight() const;
double GetScaledHeight() const;
/**
Returns the scaled size of the bitmap.
The scaled size of the bitmap is its size in pixels, as returned by
For the platforms using DPI-independent pixels, i.e. those where @c
wxHAS_DPI_INDEPENDENT_PIXELS is defined, such as wxOSX or wxGTK 3,
this function returns the physical size of the bitmap, as returned by
GetSize(), divided by its scale factor, as returned by
GetScaleFactor(), and so is the same as the normal size for bitmaps
with the default scale factor of 1 and always less than the physical
size for the higher resolution bitmaps supposed to be used on high DPI
screens.
GetScaleFactor(), while for the other platforms, it simply returns the
same thing as GetSize().
This ensures that the result of this function is always expressed in
the pixel coordinates appropriate for the current platform, i.e. its
return value is always in logical pixels, used for window and wxDC
coordinates, whether these pixels are the same as physical pixels,
which are returned by GetSize(), or not.
@see GetScaledWidth(), GetScaledHeight(), GetSize()
@since 2.9.5
*/
virtual wxSize GetScaledSize() const;
wxSize GetScaledSize() const;
/**
Returns the scaled width of the bitmap.
@@ -631,7 +653,7 @@ public:
@since 2.9.5
*/
virtual double GetScaledWidth() const;
double GetScaledWidth() const;
/**
Returns the size of the bitmap in pixels.
@@ -810,21 +832,6 @@ public:
When creating a new bitmap, CreateScaled() can be used to specify the
correct scale factor from the beginning.
Note that this method exists in all ports, but simply does nothing in
those of them that don't use logical pixel scaling. The preprocessor
symbol @c wxHAS_BITMAP_SCALE_FACTOR can be tested to determine whether
the scale factor is really supported, e.g.
@code
bitmap.SetScaleFactor(2);
// In the other ports scale factor is always 1, so the assert would
// fail there.
#ifdef wxHAS_BITMAP_SCALE_FACTOR
wxASSERT( bitmap.GetScaleFactor() == 2 );
#endif
@endcode
@since 3.1.6
*/
virtual void SetScaleFactor(double scale);

View File

@@ -1416,7 +1416,7 @@ public:
For the platforms not doing any pixel mapping, i.e. where logical and
physical pixels are one and the same, this function always returns 1.0
and so using it is, in principle, unnecessary and could be avoided by
using preprocessor check for @c wxHAVE_DPI_INDEPENDENT_PIXELS @e not
using preprocessor check for @c wxHAS_DPI_INDEPENDENT_PIXELS @e not
being defined, however using this function unconditionally under all
platforms is usually simpler and so preferable.
@@ -1424,7 +1424,7 @@ public:
3.0, but different from its behaviour in versions 3.1.0 to 3.1.3,
where it returned the same value as GetDPIScaleFactor(). Please use
the other function if you need to use a scaling factor greater than
1.0 even for the platforms without @c wxHAVE_DPI_INDEPENDENT_PIXELS,
1.0 even for the platforms without @c wxHAS_DPI_INDEPENDENT_PIXELS,
such as wxMSW.
@since 2.9.5

View File

@@ -781,22 +781,20 @@ MyFrame::MyFrame(wxWindow* parent,
// create some toolbars
wxAuiToolBar* tb1 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW);
tb1->SetToolBitmapSize(FromDIP(wxSize(48,48)));
tb1->AddTool(ID_SampleItem+1, "Test", wxArtProvider::GetBitmap(wxART_ERROR));
tb1->AddTool(ID_SampleItem+1, "Test", wxArtProvider::GetBitmapBundle(wxART_ERROR));
tb1->AddSeparator();
tb1->AddTool(ID_SampleItem+2, "Test", wxArtProvider::GetBitmap(wxART_QUESTION));
tb1->AddTool(ID_SampleItem+3, "Test", wxArtProvider::GetBitmap(wxART_INFORMATION));
tb1->AddTool(ID_SampleItem+4, "Test", wxArtProvider::GetBitmap(wxART_WARNING));
tb1->AddTool(ID_SampleItem+5, "Test", wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));
tb1->AddTool(ID_SampleItem+2, "Test", wxArtProvider::GetBitmapBundle(wxART_QUESTION));
tb1->AddTool(ID_SampleItem+3, "Test", wxArtProvider::GetBitmapBundle(wxART_INFORMATION));
tb1->AddTool(ID_SampleItem+4, "Test", wxArtProvider::GetBitmapBundle(wxART_WARNING));
tb1->AddTool(ID_SampleItem+5, "Test", wxArtProvider::GetBitmapBundle(wxART_MISSING_IMAGE));
tb1->SetCustomOverflowItems(prepend_items, append_items);
tb1->Realize();
wxAuiToolBar* tb2 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW | wxAUI_TB_HORIZONTAL);
tb2->SetToolBitmapSize(FromDIP(wxSize(16,16)));
wxBitmap tb2_bmp1 = wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, FromDIP(wxSize(16,16)));
wxBitmapBundle tb2_bmp1 = wxArtProvider::GetBitmapBundle(wxART_QUESTION, wxART_OTHER, wxSize(16,16));
tb2->AddTool(ID_SampleItem+6, "Disabled", tb2_bmp1);
tb2->AddTool(ID_SampleItem+7, "Test", tb2_bmp1);
tb2->AddTool(ID_SampleItem+8, "Test", tb2_bmp1);
@@ -816,8 +814,7 @@ MyFrame::MyFrame(wxWindow* parent,
wxAuiToolBar* tb3 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW);
tb3->SetToolBitmapSize(FromDIP(wxSize(16,16)));
wxBitmap tb3_bmp1 = wxArtProvider::GetBitmap(wxART_FOLDER, wxART_OTHER, FromDIP(wxSize(16,16)));
wxBitmapBundle tb3_bmp1 = wxArtProvider::GetBitmapBundle(wxART_FOLDER, wxART_OTHER, wxSize(16,16));
tb3->AddTool(ID_SampleItem+16, "Check 1", tb3_bmp1, "Check 1", wxITEM_CHECK);
tb3->AddTool(ID_SampleItem+17, "Check 2", tb3_bmp1, "Check 2", wxITEM_CHECK);
tb3->AddTool(ID_SampleItem+18, "Check 3", tb3_bmp1, "Check 3", wxITEM_CHECK);
@@ -839,8 +836,7 @@ MyFrame::MyFrame(wxWindow* parent,
wxAUI_TB_OVERFLOW |
wxAUI_TB_TEXT |
wxAUI_TB_HORZ_TEXT);
tb4->SetToolBitmapSize(FromDIP(wxSize(16,16)));
wxBitmap tb4_bmp1 = wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_OTHER, FromDIP(wxSize(16,16)));
wxBitmapBundle tb4_bmp1 = wxArtProvider::GetBitmapBundle(wxART_NORMAL_FILE, wxART_OTHER, wxSize(16,16));
tb4->AddTool(ID_DropDownToolbarItem, "Item 1", tb4_bmp1);
tb4->AddTool(ID_SampleItem+23, "Item 2", tb4_bmp1);
tb4->SetToolSticky(ID_SampleItem+23, true);
@@ -863,13 +859,12 @@ MyFrame::MyFrame(wxWindow* parent,
wxAuiToolBar* tb5 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW | wxAUI_TB_VERTICAL);
tb5->SetToolBitmapSize(FromDIP(wxSize(48,48)));
tb5->AddTool(ID_SampleItem+30, "Test", wxArtProvider::GetBitmap(wxART_ERROR));
tb5->AddTool(ID_SampleItem+30, "Test", wxArtProvider::GetBitmapBundle(wxART_ERROR));
tb5->AddSeparator();
tb5->AddTool(ID_SampleItem+31, "Test", wxArtProvider::GetBitmap(wxART_QUESTION));
tb5->AddTool(ID_SampleItem+32, "Test", wxArtProvider::GetBitmap(wxART_INFORMATION));
tb5->AddTool(ID_SampleItem+33, "Test", wxArtProvider::GetBitmap(wxART_WARNING));
tb5->AddTool(ID_SampleItem+34, "Test", wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));
tb5->AddTool(ID_SampleItem+31, "Test", wxArtProvider::GetBitmapBundle(wxART_QUESTION));
tb5->AddTool(ID_SampleItem+32, "Test", wxArtProvider::GetBitmapBundle(wxART_INFORMATION));
tb5->AddTool(ID_SampleItem+33, "Test", wxArtProvider::GetBitmapBundle(wxART_WARNING));
tb5->AddTool(ID_SampleItem+34, "Test", wxArtProvider::GetBitmapBundle(wxART_MISSING_IMAGE));
tb5->SetCustomOverflowItems(prepend_items, append_items);
tb5->Realize();
@@ -928,9 +923,9 @@ MyFrame::MyFrame(wxWindow* parent,
m_mgr.AddPane(wnd10, wxAuiPaneInfo().
Name("test10").Caption("Text Pane with Hide Prompt").
Bottom().Layer(1).Position(1).
Icon(wxArtProvider::GetBitmap(wxART_WARNING,
wxART_OTHER,
wxSize(iconSize, iconSize))));
Icon(wxArtProvider::GetBitmapBundle(wxART_WARNING,
wxART_OTHER,
wxSize(iconSize, iconSize))));
m_mgr.AddPane(CreateSizeReportCtrl(), wxAuiPaneInfo().
Name("test11").Caption("Fixed Pane").
@@ -1489,6 +1484,7 @@ void MyFrame::OnDropDownToolbarItem(wxAuiToolBarEvent& evt)
// create the popup menu
wxMenu menuPopup;
// TODO: Use GetBitmapBundle() when wxMenuItem is updated to use it too.
wxBitmap bmp = wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, FromDIP(wxSize(16,16)));
wxMenuItem* m1 = new wxMenuItem(&menuPopup, 10001, _("Drop Down Item 1"));
@@ -1589,11 +1585,11 @@ wxTreeCtrl* MyFrame::CreateTreeCtrl()
FromDIP(wxSize(160,250)),
wxTR_DEFAULT_STYLE | wxNO_BORDER);
wxSize size = FromDIP(wxSize(16, 16));
wxImageList* imglist = new wxImageList(size.x, size.y, true, 2);
imglist->Add(wxArtProvider::GetBitmap(wxART_FOLDER, wxART_OTHER, size));
imglist->Add(wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_OTHER, size));
tree->AssignImageList(imglist);
wxSize size(16, 16);
wxVector<wxBitmapBundle> images;
images.push_back(wxArtProvider::GetBitmapBundle(wxART_FOLDER, wxART_OTHER, size));
images.push_back(wxArtProvider::GetBitmapBundle(wxART_NORMAL_FILE, wxART_OTHER, size));
tree->SetImages(images);
wxTreeItemId root = tree->AddRoot("wxAUI Project", 0);
wxArrayTreeItemIds items;
@@ -1655,7 +1651,7 @@ wxAuiNotebook* MyFrame::CreateNotebook()
m_notebook_style);
ctrl->Freeze();
wxBitmap page_bmp = wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_OTHER, FromDIP(wxSize(16,16)));
wxBitmapBundle page_bmp = wxArtProvider::GetBitmapBundle(wxART_NORMAL_FILE, wxART_OTHER, wxSize(16,16));
ctrl->AddPage(CreateHTMLCtrl(ctrl), "Welcome to wxAUI" , false, page_bmp);
ctrl->SetPageToolTip(0, "Welcome to wxAUI (this is a page tooltip)");

View File

@@ -684,9 +684,16 @@ wxAuiDefaultDockArt::DrawIcon(wxDC& dc, wxWindow *window, const wxRect& rect, wx
wxCHECK_RET( window, "must have some window" );
}
// Ensure the icon fits into the title bar.
wxSize iconSize = pane.icon.GetPreferredSizeFor(window);
if (iconSize.y > rect.height)
{
iconSize *= static_cast<double>(rect.height) / iconSize.y;
}
// Draw the icon centered vertically
int xOffset = window->FromDIP(2);
const wxBitmap& icon = pane.icon.GetBitmapFor(window);
const wxBitmap& icon = pane.icon.GetBitmap(iconSize);
dc.DrawBitmap(icon,
rect.x+xOffset, rect.y+(rect.height-icon.GetScaledHeight())/2,
true);

View File

@@ -245,12 +245,12 @@ void wxAuiGenericTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
m_fixedTabWidth = wnd->FromDIP(100);
int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - wxWindow::FromDIP(4, NULL);
int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - wnd->FromDIP(4);
if (m_flags & wxAUI_NB_CLOSE_BUTTON)
tot_width -= m_activeCloseBmp.GetPreferredSizeFor(wnd).x;
tot_width -= m_activeCloseBmp.GetPreferredSizeFor(wnd).x / wnd->GetContentScaleFactor();
if (m_flags & wxAUI_NB_WINDOWLIST_BUTTON)
tot_width -= m_activeWindowListBmp.GetPreferredSizeFor(wnd).x;
tot_width -= m_activeWindowListBmp.GetPreferredSizeFor(wnd).x / wnd->GetContentScaleFactor();
if (tab_count > 0)
{
@@ -258,12 +258,12 @@ void wxAuiGenericTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
}
m_fixedTabWidth = wxMax(m_fixedTabWidth, wxWindow::FromDIP(100, NULL));
m_fixedTabWidth = wxMax(m_fixedTabWidth, wnd->FromDIP(100));
if (m_fixedTabWidth > tot_width/2)
m_fixedTabWidth = tot_width/2;
m_fixedTabWidth = wxMin(m_fixedTabWidth, wxWindow::FromDIP(220, NULL));
m_fixedTabWidth = wxMin(m_fixedTabWidth, wnd->FromDIP(220));
m_tabCtrlHeight = tab_ctrl_size.y;
}
@@ -703,7 +703,9 @@ wxSize wxAuiGenericTabArt::GetTabSize(wxDC& dc,
// if there's a bitmap, add space for it
if (bitmap.IsOk())
{
const wxSize bitmapSize = bitmap.GetPreferredSizeFor(wnd);
// we need the correct size of the bitmap to be used on this window in
// logical dimensions for drawing
const wxSize bitmapSize = bitmap.GetPreferredSizeFor(wnd) / wnd->GetContentScaleFactor();
// increase by bitmap plus right side bitmap padding
tab_width += bitmapSize.x + wnd->FromDIP(3);
@@ -976,7 +978,7 @@ void wxAuiSimpleTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
m_fixedTabWidth = wnd->FromDIP(100);
int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - wxWindow::FromDIP(4, NULL);
int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - wnd->FromDIP(4);
if (m_flags & wxAUI_NB_CLOSE_BUTTON)
tot_width -= m_activeCloseBmp.GetBitmapFor(wnd).GetScaledWidth();
@@ -989,12 +991,12 @@ void wxAuiSimpleTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
}
m_fixedTabWidth = wxMax(m_fixedTabWidth, wxWindow::FromDIP(100, NULL));
m_fixedTabWidth = wxMax(m_fixedTabWidth, wnd->FromDIP(100));
if (m_fixedTabWidth > tot_width/2)
m_fixedTabWidth = tot_width/2;
m_fixedTabWidth = wxMin(m_fixedTabWidth, wxWindow::FromDIP(220, NULL));
m_fixedTabWidth = wxMin(m_fixedTabWidth, wnd->FromDIP(220));
}
void wxAuiSimpleTabArt::SetColour(const wxColour& colour)

View File

@@ -138,6 +138,77 @@ wxArtProviderCache::ConstructHashID(const wxArtID& id,
wxString::Format(wxT("%d-%d"), size.x, size.y);
}
// ----------------------------------------------------------------------------
// wxBitmapBundleImplArt: uses art provider to get the bitmaps
// ----------------------------------------------------------------------------
namespace
{
class wxBitmapBundleImplArt : public wxBitmapBundleImpl
{
public:
wxBitmapBundleImplArt(const wxArtID& id,
const wxArtClient& client,
const wxSize& size)
: m_artId(id),
m_artClient(client),
m_sizeDefault(GetValidSize(id, client, size))
{
}
virtual wxSize GetDefaultSize() const wxOVERRIDE
{
return m_sizeDefault;
}
virtual wxSize GetPreferredSizeAtScale(double scale) const wxOVERRIDE
{
// We have no preferred sizes.
return m_sizeDefault*scale;
}
virtual wxBitmap GetBitmap(const wxSize& size) wxOVERRIDE
{
return wxArtProvider::GetBitmap(m_artId, m_artClient, size);
}
private:
static wxSize GetValidSize(const wxArtID& id,
const wxArtClient& client,
const wxSize& size)
{
// If valid size is provided, just use it.
if ( size != wxDefaultSize )
return size;
// Otherwise, try to get the size we'd use without creating a bitmap
// immediately.
const wxSize sizeHint = wxArtProvider::GetSizeHint(client);
if ( sizeHint != wxDefaultSize )
return sizeHint;
// If we really have to, do create a bitmap just to get its size. Note
// we need the size in logical pixels here, it will be scaled later if
// necessary, so use GetScaledSize() and not GetSize().
const wxBitmap bitmap = wxArtProvider::GetBitmap(id, client);
if ( bitmap.IsOk() )
return bitmap.GetDIPSize();
// We really need some default size, so just return this hardcoded
// value if all else fails -- what else can we do.
return wxSize(16, 16);
}
const wxArtID m_artId;
const wxArtClient m_artClient;
const wxSize m_sizeDefault;
wxDECLARE_NO_COPY_CLASS(wxBitmapBundleImplArt);
};
} // anonymous namespace
// ============================================================================
// wxArtProvider class
// ============================================================================
@@ -305,7 +376,7 @@ wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id,
wxCHECK_MSG( sm_providers, wxNullBitmap, wxT("no wxArtProvider exists") );
wxString hashId = wxArtProviderCache::ConstructHashID(id, client);
wxString hashId = wxArtProviderCache::ConstructHashID(id, client, size);
wxBitmapBundle bitmapbundle; // (DoGetIconBundle(id, client));
@@ -325,6 +396,12 @@ wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id,
return bitmapbundle;
}
wxBitmapBundle wxArtProvider::CreateBitmapBundle(const wxArtID& id,
const wxArtClient& client,
const wxSize& size)
{
return wxBitmapBundle::FromImpl(new wxBitmapBundleImplArt(id, client, size));
}
/*static*/
wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client)

View File

@@ -220,6 +220,13 @@ double wxBitmapBase::GetScaleFactor() const
return 1.0;
}
wxSize wxBitmapBase::GetDIPSize() const
{
return GetSize() / GetScaleFactor();
}
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
double wxBitmapBase::GetScaledWidth() const
{
return GetWidth() / GetScaleFactor();
@@ -235,6 +242,25 @@ wxSize wxBitmapBase::GetScaledSize() const
return wxSize(wxRound(GetScaledWidth()), wxRound(GetScaledHeight()));
}
#else // !wxHAS_DPI_INDEPENDENT_PIXELS
double wxBitmapBase::GetScaledWidth() const
{
return GetWidth();
}
double wxBitmapBase::GetScaledHeight() const
{
return GetHeight();
}
wxSize wxBitmapBase::GetScaledSize() const
{
return GetSize();
}
#endif // wxHAS_DPI_INDEPENDENT_PIXELS/!wxHAS_DPI_INDEPENDENT_PIXELS
#endif // wxUSE_BITMAP_BASE
// ----------------------------------------------------------------------------

View File

@@ -361,7 +361,7 @@ void SetScaledScreenDCFont(wxScreenDC& sDC, const wxFont& font)
{
// When using DPI-independent pixels, the results of GetTextExtent() and
// similar don't depend on DPI anyhow.
#ifndef wxHAVE_DPI_INDEPENDENT_PIXELS
#ifndef wxHAS_DPI_INDEPENDENT_PIXELS
static const int SVG_DPI = 96;
const double screenDPI = sDC.GetPPI().y;
@@ -380,7 +380,7 @@ void SetScaledScreenDCFont(wxScreenDC& sDC, const wxFont& font)
sDC.SetFont(scaledFont);
}
else
#endif // !wxHAVE_DPI_INDEPENDENT_PIXELS
#endif // !wxHAS_DPI_INDEPENDENT_PIXELS
{
sDC.SetFont(font);
}

View File

@@ -101,7 +101,7 @@ wxSize wxStaticBitmapBase::DoGetBestSize() const
//
// Note that we can use content scale factor rather than DPI scale
// because the scaled size is the same as normal size on platforms
// without wxHAVE_DPI_INDEPENDENT_PIXELS (e.g. wxMSW) anyhow.
// without wxHAS_DPI_INDEPENDENT_PIXELS (e.g. wxMSW) anyhow.
const wxSize size = m_bitmapBundle.GetPreferredSizeFor(this);
const double scale = GetContentScaleFactor();

View File

@@ -2867,7 +2867,7 @@ wxSize wxWindowBase::GetDPI() const
return wxDisplay(static_cast<const wxWindow*>(this)).GetPPI();
}
#ifndef wxHAVE_DPI_INDEPENDENT_PIXELS
#ifndef wxHAS_DPI_INDEPENDENT_PIXELS
namespace
{
@@ -2910,7 +2910,7 @@ wxWindowBase::ToDIP(const wxSize& sz, const wxWindowBase* w)
return wxRescaleCoord(sz).From(dpi).To(baseline);
}
#endif // !wxHAVE_DPI_INDEPENDENT_PIXELS
#endif // !wxHAS_DPI_INDEPENDENT_PIXELS
// Windows' computes dialog units using average character width over upper-
// and lower-case ASCII alphabet and not using the average character width

View File

@@ -489,7 +489,7 @@ bool wxHtmlWindow::DoSetPage(const wxString& source)
SetBackgroundImage(wxNullBitmap);
double pixelScale = 1.0;
#ifndef wxHAVE_DPI_INDEPENDENT_PIXELS
#ifndef wxHAS_DPI_INDEPENDENT_PIXELS
pixelScale = GetDPIScaleFactor();
#endif

View File

@@ -499,6 +499,8 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
int w = icon.GetWidth(),
h = icon.GetHeight();
refData->m_scaleFactor = icon.GetScaleFactor();
if ( iconInfo.hbmColor )
{
refData->m_width = w;
@@ -1366,18 +1368,26 @@ bool wxBitmap::InitFromHBITMAP(WXHBITMAP bmp, int width, int height, int depth)
// scale factor-related functions
// ----------------------------------------------------------------------------
// Note: currently we don't use scale factor at all and don't even store it
// because this seems useless, but we define these functions out of line here
// and not inline in the header to make it possible to change this later
// without breaking ABI if necessary.
// wxMSW doesn't really use scale factor, but we must still store it to use the
// correct sizes in the code which uses it to decide on the bitmap size to use.
void wxBitmap::SetScaleFactor(double WXUNUSED(scale))
void wxBitmap::SetScaleFactor(double scale)
{
wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
GetBitmapData()->m_scaleFactor = scale;
}
double wxBitmap::GetScaleFactor() const
{
return 1.0;
wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
return GetBitmapData()->m_scaleFactor;
}
wxSize wxBitmap::GetDIPSize() const
{
return GetSize() / GetScaleFactor();
}
double wxBitmap::GetScaledWidth() const

View File

@@ -586,7 +586,26 @@ bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
}
}
return icon->CreateFromHICON((WXHICON)hicon);
if ( !hicon )
return false;
wxSize size;
double scale = 1.0;
if ( hasSize )
{
size.x = desiredWidth;
size.y = desiredHeight;
}
else // We loaded an icon of default size.
{
// LoadIcon() returns icons of scaled size, so we must use the correct
// scaling factor of them.
size = wxGetHiconSize(hicon);
if ( const wxWindow* win = wxApp::GetMainTopWindow() )
scale = win->GetDPIScaleFactor();
}
return icon->InitFromHICON((WXHICON)hicon, size.x, size.y, scale);
}
#if wxUSE_PNG_RESOURCE_HANDLER

View File

@@ -154,7 +154,7 @@ bool wxIcon::CreateFromHICON(WXHICON icon)
return InitFromHICON(icon, size.GetWidth(), size.GetHeight());
}
bool wxIcon::InitFromHICON(WXHICON icon, int width, int height)
bool wxIcon::InitFromHICON(WXHICON icon, int width, int height, double scale)
{
#if wxDEBUG_LEVEL >= 2
if ( icon != NULL )
@@ -170,6 +170,7 @@ bool wxIcon::InitFromHICON(WXHICON icon, int width, int height)
GetGDIImageData()->m_handle = (WXHANDLE)icon;
GetGDIImageData()->m_width = width;
GetGDIImageData()->m_height = height;
GetGDIImageData()->m_scaleFactor = scale;
return IsOk();
}

View File

@@ -73,7 +73,7 @@ TEST_CASE("BitmapBundle::GetPreferredSize", "[bmpbundle]")
CHECK( b.GetPreferredSizeAtScale(3 ) == 3*normal );
}
#ifdef wxHAS_BITMAP_SCALE_FACTOR
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
TEST_CASE("BitmapBundle::Scaled", "[bmpbundle]")
{
@@ -105,7 +105,7 @@ TEST_CASE("BitmapBundle::Scaled", "[bmpbundle]")
CHECK( b.GetDefaultSize() == wxSize(32, 32) );
}
#endif // wxHAS_BITMAP_SCALE_FACTOR
#endif // wxHAS_DPI_INDEPENDENT_PIXELS
#ifdef wxHAS_SVG