From 4eae6b7ff14c6ae50cf5b391318bae1f78dc4842 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Oct 2022 16:31:52 +0200 Subject: [PATCH] Improve wxBITMAP() documentation Document wxHAS_IMAGE_RESOURCES and talk about wxBITMAP_PNG() before wxBITMAP() instead of doing it as only an afterthought. --- docs/doxygen/mainpages/const_cpp.h | 2 + docs/doxygen/overviews/bitmap.h | 92 +++++++++++++++++------------- include/wx/gdicmn.h | 2 + interface/wx/gdicmn.h | 18 ++++-- 4 files changed, 69 insertions(+), 45 deletions(-) diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index dfeaf92247..a5b687299c 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -179,6 +179,8 @@ Currently the following symbols exist: ever, be necessary to use this symbol directly, functions such as wxWindow::FromDIP() and wxBitmap::GetLogicalSize() exist to hide the differences between the platforms with and without DPI-independent pixels.} +@itemdef{wxHAS_IMAGE_RESOURCES, Defined if wxICON() and wxBITMAP() macros use + images from (Windows) resources. Otherwise, these macros use XPMs.} @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/docs/doxygen/overviews/bitmap.h b/docs/doxygen/overviews/bitmap.h index 79b3a73d77..a59d42d358 100644 --- a/docs/doxygen/overviews/bitmap.h +++ b/docs/doxygen/overviews/bitmap.h @@ -23,67 +23,79 @@ as a drawing surface. See wxMemoryDC for an example of drawing onto a bitmap. -All wxWidgets platforms support XPMs for small bitmaps and icons. You may -include the XPM inline as below, since it's C code, or you can load it at -run-time. + +@section overview_bitmap_embedding Including Bitmaps in Your Program + +It is common to need to embed some small bitmaps to be used for bitmaps or +icons in the program itself, instead of loading them from external files as +would be done for larger images. wxWidgets provides a few helper macros hiding +the differences between the platforms for doing this: wxBITMAP_PNG(), which +loads images from embedded PNG files and resources, or wxICON() and wxBITMAP() +which load images from a Windows resource of the corresponding type or from +XPM file included in the program. + +wxBITMAP_PNG() is generally better because PNG images support full alpha +channel, unlike the XPM ones, but requires converting PNG files to a C array +before including it into your program, see its documentation. If you do not +need alpha channel support, XPM images, which can be directly included into the +program are simpler to use as you only need to do the following: @code #include "sample.xpm" + +MyFrame::MyFrame() +{ + wxIcon icon(wxICON(sample)); +} @endcode -Sometimes you wish to use a .ico resource on Windows, and XPMs on other -platforms (for example to take advantage of Windows' support for multiple icon -resolutions). - -A macro, wxICON(), is available which creates an icon using an XPM on the -appropriate platform, or an icon resource on Windows: +which is equivalent to @code -wxIcon icon(wxICON(sample)); - -// The above line is equivalent to this: +#include "sample.xpm" +MyFrame::MyFrame() +{ #if defined(__WXGTK__) wxIcon icon(sample_xpm); #endif +// ... similar checks for other platforms ... + #if defined(__WXMSW__) - wxIcon icon("sample"); + wxIcon icon("sample"); // loaded from Windows resources (.rc file) #endif +} @endcode -There is also a corresponding wxBITMAP() macro which allows to create the -bitmaps in much the same way as wxICON() creates icons. It assumes that bitmaps -live in resources under Windows and XPM files under all other platforms -(for XPMs, the corresponding file must be included before this macro is used, -of course, and the name of the bitmap should be the same as the resource name -under Windows with @c _xpm suffix). For example: +but is, of course, much simpler and more clear. There is also a corresponding +wxBITMAP() macro which works in the same way but +creates a wxBitmap rather than wxIcon. + +Note that including XPM files under Windows is harmless, but not really +necessary, as they are not used there and can be avoided by testing for +`wxHAS_IMAGES_IN_RESOURCES` symbol, i.e. you would typically do @code -// an easy and portable way to create a bitmap -wxBitmap bmp(wxBITMAP(bmpname)); - -// which is roughly equivalent to the following -#if defined(__WXMSW__) - wxBitmap bmp("bmpname", wxBITMAP_TYPE_BMP_RESOURCE); -#else // Unix - wxBitmap bmp(bmpname_xpm, wxBITMAP_TYPE_XPM); +#ifndef wxHAS_IMAGES_IN_RESOURCES + #include "bitmaps/north.xpm" + #include "bitmaps/south.xpm" + #include "bitmaps/east.xpm" + #include "bitmaps/west.xpm" #endif + +MyFrame::MyFrame() +{ + wxBitmap bmpN = wxBITMAP(north); + ... +} @endcode -You should always use wxICON() and wxBITMAP() macros because they work for any -platform (unlike the code above which doesn't deal with wxMac, wxX11, ...) and -are shorter and more clear than versions with many @ifdef_ blocks. -Alternatively, you could use the same XPMs on all platforms and avoid dealing -with Windows resource files. - -If you'd like to embed bitmaps with alpha transparency in your program, neither -XPM nor BMP formats are appropriate as they don't have support for alpha and -another format, typically PNG, should be used. wxWidgets provides a similar -helper for PNG bitmaps called wxBITMAP_PNG() that can be used to either load -PNG files embedded in resources (meaning either Windows resource section of the -executable file or macOS "Resource" subdirectory of the application bundle) or -arrays containing PNG data included into the program code itself. +Finally note that you may also want to use XPMs under all platforms, including +Windows, for simplicity, and to avoid having to deal with Windows resource +files (however you still need to define the application icon there). In this +case you should _not_ use wxICON() and wxBITMAP() macros as they expect to find +the images in Windows resources when building Windows programs. @see @ref group_class_gdi diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index f549126401..058776ff8d 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -231,6 +231,8 @@ enum wxEllipsizeMode /* Another macro: this one is for portable creation of bitmaps. We assume that under Unix bitmaps live in XPMs and under Windows they're in resources. + + This is a legacy macro, prefer using wxBITMAP_PNG() in the new code. */ #if defined(__WINDOWS__) && wxUSE_WXDIB diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 896402e7fa..383a0f6307 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -1130,9 +1130,13 @@ const wxSize wxDefaultSize; /** This macro loads a bitmap from either application resources (on the platforms for which they exist, i.e.\ Windows) or from an XPM file. - This can help to avoid using @ifdef_ when creating bitmaps. - @see @ref overview_bitmap, wxICON() + You can use `wxHAS_IMAGES_IN_RESOURCES` to check if the XPM needs to be + included when using this macro. + + See also wxBITMAP_PNG() if you want to use images with alpha channel. + + @see @ref overview_bitmap_embedding, wxICON() @header{wx/gdicmn.h} */ @@ -1176,7 +1180,7 @@ const wxSize wxDefaultSize; @endcode in your application startup code. - @see wxBITMAP_PNG_FROM_DATA() + @see @ref overview_bitmap_embedding, wxBITMAP_PNG_FROM_DATA() @header{wx/gdicmn.h} @@ -1208,9 +1212,13 @@ const wxSize wxDefaultSize; /** This macro loads an icon from either application resources (on the platforms for which they exist, i.e.\ Windows) or from an XPM file. - This can help to avoid using @ifdef_ when creating icons. - @see @ref overview_bitmap, wxBITMAP() + You can use `wxHAS_IMAGES_IN_RESOURCES` to check if the XPM needs to be + included when using this macro. + + See also wxBITMAP_PNG() if you want to use images with alpha channel. + + @see @ref overview_bitmap_embedding, wxBITMAP() @header{wx/gdicmn.h} */