/////////////////////////////////////////////////////////////////////////////// // 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_