wxWidgets/include/wx/bmpbndl.h
Vadim Zeitlin f48a13514f Allow constructing wxBitmapBundle from XPM data for compatibility
Add another compatibility implicit constructor to allow the existing
code, directly passing XPM data to various functions that used to take
wxBitmap or wxIcon and now taking wxBitmapBundle, to work.

Closes #22566.
2022-06-26 20:52:13 +02:00

293 lines
12 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: wx/bmpbndl.h
// Purpose: Declaration of wxBitmapBundle class.
// Author: Vadim Zeitlin
// Created: 2021-09-22
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_BMPBNDL_H_
#define _WX_BMPBNDL_H_
#include "wx/bitmap.h"
#include "wx/object.h"
#include "wx/vector.h"
class wxBitmapBundleImpl;
class WXDLLIMPEXP_FWD_CORE wxIconBundle;
class WXDLLIMPEXP_FWD_CORE wxImageList;
class WXDLLIMPEXP_FWD_CORE wxWindow;
// ----------------------------------------------------------------------------
// wxBitmapBundle provides 1 or more versions of a bitmap, all bundled together
// ----------------------------------------------------------------------------
// This class has value semantics and can be copied cheaply.
class WXDLLIMPEXP_CORE wxBitmapBundle
{
public:
// Default ctor constructs an empty bundle which can't be used for
// anything, but can be assigned something later.
wxBitmapBundle();
// This conversion ctor from a single bitmap does the same thing as
// FromBitmap() and only exists for interoperability with the existing code
// using wxBitmap.
wxBitmapBundle(const wxBitmap& bitmap);
// This is similar to above and also exists only for compatibility.
wxBitmapBundle(const wxIcon& icon);
// Another conversion ctor from a single image: this one is needed to allow
// passing wxImage to the functions that used to take wxBitmap but now take
// wxBitmapBundle.
wxBitmapBundle(const wxImage& image);
// And another one from XPM data, as it's relatively common to pass it to
// various functions that take wxBitmapBundle in the existing code. It is
// not formally deprecated, but should be avoided in any new code and can
// become deprecated in the future.
wxBitmapBundle(const char* const* xpm);
// Default copy ctor and assignment operator and dtor would be ok, but need
// to be defined out of line, where wxBitmapBundleImpl is fully declared.
wxBitmapBundle(const wxBitmapBundle& other);
wxBitmapBundle& operator=(const wxBitmapBundle& other);
~wxBitmapBundle();
// Create from the given collection of bitmaps (all of which must be valid,
// but if the vector itself is empty, empty bundle is returned).
static wxBitmapBundle FromBitmaps(const wxVector<wxBitmap>& bitmaps);
static wxBitmapBundle FromBitmaps(const wxBitmap& bitmap1,
const wxBitmap& bitmap2);
// Create from a single bitmap (this is only useful for compatibility
// with the existing code). Returns empty bundle if bitmap is invalid.
static wxBitmapBundle FromBitmap(const wxBitmap& bitmap);
static wxBitmapBundle FromImage(const wxImage& image);
// Create from icon bundle.
static wxBitmapBundle FromIconBundle(const wxIconBundle& iconBundle);
// It should be possible to implement SVG rasterizing without raw bitmap
// support using wxDC::DrawSpline(), but currently we don't do it and so
// FromSVG() is only available in the ports providing raw bitmap access.
#ifdef wxHAS_SVG
// Create from the SVG data (data is supposed to be in UTF-8 encoding).
// Notice that the data here is non-const because it can be temporarily
// modified while parsing it.
static wxBitmapBundle FromSVG(char* data, const wxSize& sizeDef);
// This overload currently makes a copy of the data.
static wxBitmapBundle FromSVG(const char* data, const wxSize& sizeDef);
// This overload works for data not terminated with 0
static wxBitmapBundle FromSVG(const wxByte* data, size_t len, const wxSize& sizeDef);
// Load SVG image from the given file (must be a local file, not an URL).
static wxBitmapBundle FromSVGFile(const wxString& path, const wxSize& sizeDef);
// Create from SVG image stored as an application resource.
// On Windows, name must be a resource with RT_RCDATA type.
// On MacOS, name must be a file with an extension "svg" placed in the
// "Resources" subdirectory of the application bundle.
static wxBitmapBundle FromSVGResource(const wxString& name, const wxSize& sizeDef);
#endif // wxHAS_SVG
// Create from the resources: all existing versions of the bitmap of the
// form name_2x or name@2x (and also using other factors) will be used.
static wxBitmapBundle FromResources(const wxString& name);
// Create from files: all existing versions of the bitmap of the
// form filename_2x or name@2x (and also using other factors) will be used.
static wxBitmapBundle FromFiles(const wxString& fullpathname);
static wxBitmapBundle FromFiles(const wxString& path, const wxString& filename, const wxString& extension = wxASCII_STR("png"));
// Create from existing implementation
static wxBitmapBundle FromImpl(wxBitmapBundleImpl* impl);
// Check if bitmap bundle is non-empty.
bool IsOk() const { return m_impl.get() != NULL; }
// Clear the bundle contents, IsOk() will return false after doing this.
void Clear();
// Get the size of the bitmap represented by this bundle when using the
// default DPI, i.e. 100% scaling. Returns invalid size for empty bundle.
wxSize GetDefaultSize() const;
// Get the physical size of the preferred bitmap at the given scale.
wxSize GetPreferredBitmapSizeAtScale(double scale) const;
// Get preferred size, i.e. usually the closest size in which a bitmap is
// available to the ideal size determined from the default size and the DPI
// scaling, for the given window, in physical/logical pixels respectively.
wxSize GetPreferredBitmapSizeFor(const wxWindow* window) const;
wxSize GetPreferredLogicalSizeFor(const wxWindow* window) const;
// Get bitmap of the specified size, creating a new bitmap from the closest
// available size by rescaling it if necessary.
//
// If size == wxDefaultSize, GetDefaultSize() is used for it instead.
wxBitmap GetBitmap(const wxSize& size) const;
// Get icon of the specified size, this is just a convenient wrapper for
// GetBitmap() converting the returned bitmap to the icon.
wxIcon GetIcon(const wxSize& size) const;
// Helpers combining GetPreferredBitmapSizeFor() and GetBitmap() or
// GetIcon(): return the bitmap or icon of the size appropriate for the
// current DPI scaling of the given window.
wxBitmap GetBitmapFor(const wxWindow* window) const;
wxIcon GetIconFor(const wxWindow* window) const;
// Access implementation
wxBitmapBundleImpl* GetImpl() const { return m_impl.get(); }
// Check if two objects refer to the same bundle.
bool IsSameAs(const wxBitmapBundle& other) const
{
return GetImpl() == other.GetImpl();
}
// Implementation only from now on.
// Get the bitmap size preferred by the majority of the elements of the
// bundles at the given scale or the scale appropriate for the given window.
static wxSize
GetConsensusSizeFor(double scale, const wxVector<wxBitmapBundle>& bundles);
static wxSize
GetConsensusSizeFor(wxWindow* win, const wxVector<wxBitmapBundle>& bundles);
// Create wxImageList and fill it with the images from the given bundles in
// the sizes appropriate for the DPI scaling used for the specified window.
static wxImageList*
CreateImageList(wxWindow* win, const wxVector<wxBitmapBundle>& bundles);
private:
typedef wxObjectDataPtr<wxBitmapBundleImpl> wxBitmapBundleImplPtr;
// Private ctor used by static factory functions to create objects of this
// class. It takes ownership of the pointer (which must be non-null).
explicit wxBitmapBundle(wxBitmapBundleImpl* impl);
wxBitmapBundleImplPtr m_impl;
};
// This macro can be used to create a bundle from resources on the platforms
// that support it and from name_png and name_2x_png on the other ones.
#ifdef wxHAS_IMAGE_RESOURCES
#define wxBITMAP_BUNDLE_2(name) wxBitmapBundle::FromResources(#name)
#else
#define wxBITMAP_BUNDLE_2(name) \
wxBitmapBundle::FromBitmaps(wxBITMAP_PNG_FROM_DATA(name), \
wxBITMAP_PNG_FROM_DATA(name##_2x))
#endif
// Inline functions implementation.
/* static */ inline
wxBitmapBundle wxBitmapBundle::FromBitmaps(const wxBitmap& bitmap1,
const wxBitmap& bitmap2)
{
wxVector<wxBitmap> bitmaps;
if ( bitmap1.IsOk() )
bitmaps.push_back(bitmap1);
if ( bitmap2.IsOk() )
bitmaps.push_back(bitmap2);
return FromBitmaps(bitmaps);
}
/* static */ inline
wxBitmapBundle wxBitmapBundle::FromBitmap(const wxBitmap& bitmap)
{
return wxBitmapBundle(bitmap);
}
/* static */ inline
wxBitmapBundle wxBitmapBundle::FromImage(const wxImage& image)
{
if ( !image.IsOk() )
return wxBitmapBundle();
return FromBitmap(wxBitmap(image));
}
// ----------------------------------------------------------------------------
// wxBitmapBundleImpl is the base class for all wxBitmapBundle implementations
// ----------------------------------------------------------------------------
// This class inherits from wxRefCounter to make it possible to use it with
// wxObjectDataPtr in wxBitmapBundle.
//
// It doesn't need to be used directly, but may be inherited from in order to
// implement custom bitmap bundles.
class WXDLLIMPEXP_CORE wxBitmapBundleImpl : public wxRefCounter
{
protected:
// Standard implementation of GetPreferredBitmapSizeAtScale(): choose the
// scale closest to the given one from the available bitmap scales.
//
// If this function is used, GetNextAvailableScale() must be overridden!
wxSize DoGetPreferredSize(double scale) const;
// Helper for implementing GetBitmap(): if we need to upscale a bitmap,
// uses GetNextAvailableScale() to find the index of the best bitmap to
// use, where "best" is defined as "using scale which is a divisor of the
// given one", as upscaling by an integer factor is strongly preferable.
size_t GetIndexToUpscale(const wxSize& size) const;
// Override this function if DoGetPreferredSize() or GetIndexToUpscale() is
// used: it can use the provided parameter as an internal index, it's
// guaranteed to be 0 when calling this function for the first time. When
// there are no more scales, return 0.
//
// This function is not pure virtual because it doesn't need to be
// implemented if DoGetPreferredSize() is never used, but it will assert if
// it's called.
virtual double GetNextAvailableScale(size_t& i) const;
virtual ~wxBitmapBundleImpl();
public:
// Return the size of the bitmaps represented by this bundle in the default
// DPI (a.k.a. 100% resolution).
//
// Must always return a valid size.
virtual wxSize GetDefaultSize() const = 0;
// Return the preferred size that should be used at the given scale.
//
// Must always return a valid size.
virtual wxSize GetPreferredBitmapSizeAtScale(double scale) const = 0;
// Retrieve the bitmap of exactly the given size.
//
// Note that this function is non-const because it may generate the bitmap
// on demand and cache it.
virtual wxBitmap GetBitmap(const wxSize& size) = 0;
};
// ----------------------------------------------------------------------------
// Allow using wxBitmapBundle in wxVariant
// ----------------------------------------------------------------------------
#if wxUSE_VARIANT
class WXDLLIMPEXP_FWD_BASE wxVariant;
WXDLLIMPEXP_CORE
wxBitmapBundle& operator<<(wxBitmapBundle& value, const wxVariant& variant);
WXDLLIMPEXP_CORE
wxVariant& operator<<(wxVariant& variant, const wxBitmapBundle& value);
#endif // wxUSE_VARIANT
#endif // _WX_BMPBNDL_H_