diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index 919e0c54c4..75a5b56c8d 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -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 diff --git a/include/wx/artprov.h b/include/wx/artprov.h index b8cbd199b1..dd067d5144 100644 --- a/include/wx/artprov.h +++ b/include/wx/artprov.h @@ -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)) diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index 8713884001..67bed4ce30 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -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; diff --git a/include/wx/features.h b/include/wx/features.h index 7f28d4915e..e2dd300e58 100644 --- a/include/wx/features.h +++ b/include/wx/features.h @@ -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_ */ diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index f79c081393..975dff950f 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -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; diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 21ebdec47f..a3c6d1279b 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -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 // ------------------------------- diff --git a/include/wx/msw/gdiimage.h b/include/wx/msw/gdiimage.h index 94b6f01091..39f8af2979 100644 --- a/include/wx/msw/gdiimage.h +++ b/include/wx/msw/gdiimage.h @@ -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 { diff --git a/include/wx/msw/icon.h b/include/wx/msw/icon.h index 2c89f2597a..294e4577b1 100644 --- a/include/wx/msw/icon.h +++ b/include/wx/msw/icon.h @@ -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 diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index 47c7e5fdc1..c8173abc59 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -13,8 +13,6 @@ #include "wx/palette.h" -#define wxHAS_BITMAP_SCALE_FACTOR - // Bitmap class WXDLLIMPEXP_FWD_CORE wxBitmap; class wxBitmapRefData ; diff --git a/include/wx/window.h b/include/wx/window.h index c9b8869895..48efebc63d 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -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); diff --git a/interface/wx/artprov.h b/interface/wx/artprov.h index 8f0c1ff0d7..e8b0931783 100644 --- a/interface/wx/artprov.h +++ b/interface/wx/artprov.h @@ -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 diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index c45a34a583..c1605c0523 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -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); diff --git a/interface/wx/window.h b/interface/wx/window.h index 93186d4189..98f20adce4 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -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 diff --git a/samples/aui/auidemo.cpp b/samples/aui/auidemo.cpp index 2593018dcd..1e415b311b 100644 --- a/samples/aui/auidemo.cpp +++ b/samples/aui/auidemo.cpp @@ -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 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)"); diff --git a/src/aui/dockart.cpp b/src/aui/dockart.cpp index 51f0fbb724..8a1c4868e2 100644 --- a/src/aui/dockart.cpp +++ b/src/aui/dockart.cpp @@ -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(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); diff --git a/src/aui/tabart.cpp b/src/aui/tabart.cpp index ef12247cc7..8ceb85d5cb 100644 --- a/src/aui/tabart.cpp +++ b/src/aui/tabart.cpp @@ -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) diff --git a/src/common/artprov.cpp b/src/common/artprov.cpp index 66327070fb..4a06f88e96 100644 --- a/src/common/artprov.cpp +++ b/src/common/artprov.cpp @@ -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) diff --git a/src/common/bmpbase.cpp b/src/common/bmpbase.cpp index 1b76bc3a1a..3cb1c75471 100644 --- a/src/common/bmpbase.cpp +++ b/src/common/bmpbase.cpp @@ -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 // ---------------------------------------------------------------------------- diff --git a/src/common/dcsvg.cpp b/src/common/dcsvg.cpp index 96efcccc1c..6104c349d3 100644 --- a/src/common/dcsvg.cpp +++ b/src/common/dcsvg.cpp @@ -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); } diff --git a/src/common/statbmpcmn.cpp b/src/common/statbmpcmn.cpp index 013e40cb97..95500ba1d1 100644 --- a/src/common/statbmpcmn.cpp +++ b/src/common/statbmpcmn.cpp @@ -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(); diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 63b59a62ad..09f15fca0b 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -2867,7 +2867,7 @@ wxSize wxWindowBase::GetDPI() const return wxDisplay(static_cast(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 diff --git a/src/html/htmlwin.cpp b/src/html/htmlwin.cpp index 63a14ab885..835de23b05 100644 --- a/src/html/htmlwin.cpp +++ b/src/html/htmlwin.cpp @@ -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 diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index c63dd61089..86b936ef3a 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -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 diff --git a/src/msw/gdiimage.cpp b/src/msw/gdiimage.cpp index 6b43e76c5d..fe2d3b2b52 100644 --- a/src/msw/gdiimage.cpp +++ b/src/msw/gdiimage.cpp @@ -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 diff --git a/src/msw/icon.cpp b/src/msw/icon.cpp index 37758ee692..e2dedb2cc0 100644 --- a/src/msw/icon.cpp +++ b/src/msw/icon.cpp @@ -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(); } diff --git a/tests/graphics/bmpbundle.cpp b/tests/graphics/bmpbundle.cpp index cebbc0c110..b0f7cac236 100644 --- a/tests/graphics/bmpbundle.cpp +++ b/tests/graphics/bmpbundle.cpp @@ -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