diff --git a/docs/changes.txt b/docs/changes.txt index 04a1c2a2a2..5d2d9d12cd 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -183,6 +183,9 @@ Changes in behaviour which may result in build errors - wxGridEvent methods GetRow() and GetCol() are no longer virtual. +- wxImage constructor from XPM data is now explicit, write "wxImage(xpmData)" + instead of just "xpmData" if you really need to use it. + 3.1.6: (released 2021-06-??) ---------------------------- diff --git a/include/wx/dfb/cursor.h b/include/wx/dfb/cursor.h index e1f6fe5257..86b2e8531d 100644 --- a/include/wx/dfb/cursor.h +++ b/include/wx/dfb/cursor.h @@ -11,6 +11,7 @@ #define _WX_DFB_CURSOR_H_ class WXDLLIMPEXP_FWD_CORE wxBitmap; +class WXDLLIMPEXP_FWD_CORE wxImage; //----------------------------------------------------------------------------- // wxCursor @@ -24,6 +25,10 @@ public: #if WXWIN_COMPATIBILITY_2_8 wxCursor(int id) { InitFromStock((wxStockCursor)id); } #endif +#if wxUSE_IMAGE + wxCursor(const wxImage& image); + wxCursor(const char* const* xpmData); +#endif // wxUSE_IMAGE wxCursor(const wxString& name, wxBitmapType type = wxCURSOR_DEFAULT_TYPE, int hotSpotX = 0, int hotSpotY = 0); diff --git a/include/wx/gtk/cursor.h b/include/wx/gtk/cursor.h index 51d106d445..439cbf91d4 100644 --- a/include/wx/gtk/cursor.h +++ b/include/wx/gtk/cursor.h @@ -25,10 +25,11 @@ public: #endif #if wxUSE_IMAGE wxCursor( const wxImage & image ); + wxCursor(const char* const* xpmData); +#endif // wxUSE_IMAGE wxCursor(const wxString& name, wxBitmapType type = wxCURSOR_DEFAULT_TYPE, int hotSpotX = 0, int hotSpotY = 0); -#endif wxCursor( const char bits[], int width, int height, int hotSpotX = -1, int hotSpotY = -1, const char maskBits[] = NULL, diff --git a/include/wx/image.h b/include/wx/image.h index 2a0cb489b5..125b8c707d 100644 --- a/include/wx/image.h +++ b/include/wx/image.h @@ -310,7 +310,7 @@ public: { LoadFile( name, type, index ); } wxImage( const wxString& name, const wxString& mimetype, int index = -1 ) { LoadFile( name, mimetype, index ); } - wxImage( const char* const* xpmData ) + explicit wxImage( const char* const* xpmData ) { Create(xpmData); } #if wxUSE_STREAMS diff --git a/include/wx/motif/cursor.h b/include/wx/motif/cursor.h index e59521a7c2..6fdf541f75 100644 --- a/include/wx/motif/cursor.h +++ b/include/wx/motif/cursor.h @@ -32,6 +32,7 @@ public: #if wxUSE_IMAGE wxCursor(const wxImage& image); + wxCursor(const char* const* xpmData); #endif wxCursor(wxStockCursor id) { InitFromStock(id); } @@ -52,6 +53,10 @@ protected: private: void InitFromStock(wxStockCursor); +#if wxUSE_IMAGE + void InitFromImage(const wxImage& image); +#endif + void Create(const char bits[], int width, int height, int hotSpotX = -1, int hotSpotY = -1, const char maskBits[] = NULL); diff --git a/include/wx/msw/cursor.h b/include/wx/msw/cursor.h index 786d4bf2a8..93fc83c31e 100644 --- a/include/wx/msw/cursor.h +++ b/include/wx/msw/cursor.h @@ -19,7 +19,10 @@ class WXDLLIMPEXP_CORE wxCursor : public wxCursorBase public: // constructors wxCursor(); +#if wxUSE_IMAGE wxCursor(const wxImage& image); + wxCursor(const char* const* xpmData); +#endif // wxUSE_IMAGE wxCursor(const wxString& name, wxBitmapType type = wxCURSOR_DEFAULT_TYPE, int hotSpotX = 0, int hotSpotY = 0); @@ -42,6 +45,10 @@ protected: virtual wxGDIImageRefData *CreateData() const wxOVERRIDE; private: +#if wxUSE_IMAGE + void InitFromImage(const wxImage& image); +#endif // wxUSE_IMAGE + wxDECLARE_DYNAMIC_CLASS(wxCursor); }; diff --git a/include/wx/osx/cursor.h b/include/wx/osx/cursor.h index ae3eb2463a..d01a643c62 100644 --- a/include/wx/osx/cursor.h +++ b/include/wx/osx/cursor.h @@ -19,7 +19,10 @@ class WXDLLIMPEXP_CORE wxCursor : public wxCursorBase public: wxCursor(); +#if wxUSE_IMAGE wxCursor(const wxImage & image) ; + wxCursor(const char* const* xpmData); +#endif // wxUSE_IMAGE wxCursor(const wxString& name, wxBitmapType type = wxCURSOR_DEFAULT_TYPE, int hotSpotX = 0, int hotSpotY = 0); @@ -42,7 +45,9 @@ protected: private: void InitFromStock(wxStockCursor); - void CreateFromImage(const wxImage & image) ; +#if wxUSE_IMAGE + void InitFromImage(const wxImage & image) ; +#endif // wxUSE_IMAGE wxDECLARE_DYNAMIC_CLASS(wxCursor); }; diff --git a/include/wx/qt/cursor.h b/include/wx/qt/cursor.h index 92f0a7bc8c..763d61c8d0 100644 --- a/include/wx/qt/cursor.h +++ b/include/wx/qt/cursor.h @@ -22,10 +22,11 @@ public: #endif #if wxUSE_IMAGE wxCursor( const wxImage & image ); + wxCursor(const char* const* xpmData); +#endif // wxUSE_IMAGE wxCursor(const wxString& name, wxBitmapType type = wxCURSOR_DEFAULT_TYPE, int hotSpotX = 0, int hotSpotY = 0); -#endif virtual wxPoint GetHotSpot() const wxOVERRIDE; QCursor &GetHandle() const; diff --git a/include/wx/x11/cursor.h b/include/wx/x11/cursor.h index 36c8f0e839..b9bdc11d39 100644 --- a/include/wx/x11/cursor.h +++ b/include/wx/x11/cursor.h @@ -29,6 +29,7 @@ public: #endif #if wxUSE_IMAGE wxCursor( const wxImage & image ); + wxCursor(const char* const* xpmData); #endif wxCursor(const wxString& name, diff --git a/interface/wx/cursor.h b/interface/wx/cursor.h index 2d6199c5d8..4617edd18a 100644 --- a/interface/wx/cursor.h +++ b/interface/wx/cursor.h @@ -190,6 +190,17 @@ public: */ wxCursor(const wxImage& image); + /** + Constructs a cursor from XPM data. + + In versions of wxWidgets until 3.1.6 constructing wxCursor from XPM + data implicitly used wxImage constructor from XPM data and wxCursor + constructor from wxImage. Since 3.1.6 this constructor overload is + available to allow constructing wxCursor from XPM to still work, even + though wxImage constructor from XPM is now @c explicit. + */ + wxCursor(const char* const* xpmData); + /** Copy constructor, uses @ref overview_refcount "reference counting". diff --git a/interface/wx/image.h b/interface/wx/image.h index 85506f3ad4..2bf152168c 100644 --- a/interface/wx/image.h +++ b/interface/wx/image.h @@ -611,8 +611,10 @@ public: @beginWxPerlOnly Not supported by wxPerl. @endWxPerlOnly + + This constructor has become @c explicit in wxWidgets 3.1.6. */ - wxImage(const char* const* xpmData); + explicit wxImage(const char* const* xpmData); /** Creates an image from a file. diff --git a/src/dfb/cursor.cpp b/src/dfb/cursor.cpp index 8a9799d5d2..00ced6480f 100644 --- a/src/dfb/cursor.cpp +++ b/src/dfb/cursor.cpp @@ -53,6 +53,20 @@ void wxCursor::InitFromStock(wxStockCursor cursorId) #warning "FIXME -- implement the cursor as bitmaps (that's what DFB uses)" } +#if wxUSE_IMAGE + +wxCursor::wxCursor(const wxImage& image) +{ +#warning "FIXME" +} + +wxCursor::wxCursor(const char* const* xpmData) +{ +#warning "FIXME" +} + +#endif // wxUSE_IMAGE + wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType type, int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY)) diff --git a/src/gtk/cursor.cpp b/src/gtk/cursor.cpp index 07fe835b85..87fac1ab8f 100644 --- a/src/gtk/cursor.cpp +++ b/src/gtk/cursor.cpp @@ -72,11 +72,11 @@ wxCursor::wxCursor() { } -#if wxUSE_IMAGE wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType type, int hotSpotX, int hotSpotY) { +#if wxUSE_IMAGE wxImage img; if (!img.LoadFile(cursor_file, type)) return; @@ -88,13 +88,20 @@ wxCursor::wxCursor(const wxString& cursor_file, img.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY); InitFromImage(img); +#endif // wxUSE_IMAGE } +#if wxUSE_IMAGE wxCursor::wxCursor(const wxImage& img) { InitFromImage(img); } -#endif + +wxCursor::wxCursor(const char* const* xpmData) +{ + InitFromImage(wxImage(xpmData)); +} +#endif // wxUSE_IMAGE wxCursor::wxCursor(const char bits[], int width, int height, int hotSpotX, int hotSpotY, diff --git a/src/motif/cursor.cpp b/src/motif/cursor.cpp index ba23046ea7..68579ce2cc 100644 --- a/src/motif/cursor.cpp +++ b/src/motif/cursor.cpp @@ -93,7 +93,7 @@ wxCursor::wxCursor() } #if wxUSE_IMAGE -wxCursor::wxCursor(const wxImage & image) +void wxCursor::InitFromImage(const wxImage & image) { unsigned char * rgbBits = image.GetData(); int w = image.GetWidth() ; @@ -174,6 +174,16 @@ wxCursor::wxCursor(const wxImage & image) delete[] bits; delete[] maskBits; } + +wxCursor::wxCursor(const wxImage& image) +{ + InitFromImage(image); +} + +wxCursor::wxCursor(const char* const* xpmData) +{ + InitFromImage(wxImage(xpmData)); +} #endif void wxCursor::Create(const char bits[], int width, int height, diff --git a/src/msw/cursor.cpp b/src/msw/cursor.cpp index e37727a59d..6b7b9c5019 100644 --- a/src/msw/cursor.cpp +++ b/src/msw/cursor.cpp @@ -153,6 +153,16 @@ wxCursor::wxCursor() #if wxUSE_IMAGE wxCursor::wxCursor(const wxImage& image) +{ + InitFromImage(image); +} + +wxCursor::wxCursor(const char* const* xpmData) +{ + InitFromImage(wxImage(xpmData)); +} + +void wxCursor::InitFromImage(const wxImage& image) { // image has to be of the standard cursor size, otherwise we won't be able // to create it diff --git a/src/osx/carbon/cursor.cpp b/src/osx/carbon/cursor.cpp index 7b83407bcb..7e44649bcf 100644 --- a/src/osx/carbon/cursor.cpp +++ b/src/osx/carbon/cursor.cpp @@ -225,13 +225,18 @@ wxCursor::wxCursor() { } +#if wxUSE_IMAGE wxCursor::wxCursor( const wxImage &image ) { -#if wxUSE_IMAGE - CreateFromImage( image ) ; -#endif + InitFromImage( image ) ; } +wxCursor::wxCursor(const char* const* xpmData) +{ + InitFromImage( wxImage(xpmData) ) ; +} +#endif // wxUSE_IMAGE + wxGDIRefData *wxCursor::CreateGDIRefData() const { return new wxCursorRefData; @@ -249,7 +254,7 @@ WXHCURSOR wxCursor::GetHCURSOR() const #if wxUSE_IMAGE -void wxCursor::CreateFromImage(const wxImage & image) +void wxCursor::InitFromImage(const wxImage & image) { m_refData = new wxCursorRefData; int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); @@ -287,7 +292,7 @@ wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType flags, int hotSpotX image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY ) ; m_refData->DecRef() ; m_refData = NULL ; - CreateFromImage( image ) ; + InitFromImage( image ) ; } #endif } diff --git a/src/qt/cursor.cpp b/src/qt/cursor.cpp index 002fa63c08..a52f5a8211 100644 --- a/src/qt/cursor.cpp +++ b/src/qt/cursor.cpp @@ -59,11 +59,11 @@ public: wxIMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject); -#if wxUSE_IMAGE wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType type, int hotSpotX, int hotSpotY) { +#if wxUSE_IMAGE wxImage img; if (!img.LoadFile(cursor_file, type)) return; @@ -75,13 +75,20 @@ wxCursor::wxCursor(const wxString& cursor_file, img.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY); InitFromImage(img); +#endif // wxUSE_IMAGE } +#if wxUSE_IMAGE wxCursor::wxCursor(const wxImage& img) { InitFromImage(img); } -#endif + +wxCursor::wxCursor(const char* const* xpmData) +{ + InitFromImage(wxImage(xpmData)); +} +#endif // wxUSE_IMAGE wxPoint wxCursor::GetHotSpot() const { diff --git a/src/x11/cursor.cpp b/src/x11/cursor.cpp index d12d15314b..8fe903b05e 100644 --- a/src/x11/cursor.cpp +++ b/src/x11/cursor.cpp @@ -140,6 +140,11 @@ wxCursor::wxCursor( const wxImage & WXUNUSED(image) ) { wxFAIL_MSG( wxT("wxCursor creation from wxImage not yet implemented") ); } + +wxCursor::wxCursor(const char* const* WXUNUSED(xpmData)) +{ + wxFAIL_MSG( wxT("wxCursor creation from XPM not yet implemented") ); +} #endif wxCursor::~wxCursor() diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 65225f55d9..af70bc21ee 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -21,6 +21,8 @@ #include "wx/anidecod.h" // wxImageArray #include "wx/bitmap.h" +#include "wx/cursor.h" +#include "wx/icon.h" #include "wx/palette.h" #include "wx/url.h" #include "wx/log.h" @@ -2164,6 +2166,40 @@ TEST_CASE("wxImage::InitAlpha", "[image][initalpha]") } } +TEST_CASE("wxImage::XPM", "[image][xpm]") +{ + static const char * dummy_xpm[] = { + "16 16 2 1", + "@ c Black", + " c None", + "@ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @ ", + " @" + }; + + wxImage image(dummy_xpm); + CHECK( image.IsOk() ); + + // The goal here is mostly just to check that this code compiles, i.e. that + // creating all these classes from XPM works. + CHECK( wxBitmap(dummy_xpm).IsOk() ); + CHECK( wxCursor(dummy_xpm).IsOk() ); + CHECK( wxIcon(dummy_xpm).IsOk() ); +} + /* TODO: add lots of more tests to wxImage functions */