diff --git a/include/wx/artprov.h b/include/wx/artprov.h index 85fb9f6565..7bf65efbc4 100644 --- a/include/wx/artprov.h +++ b/include/wx/artprov.h @@ -15,6 +15,7 @@ #include "wx/bitmap.h" #include "wx/icon.h" #include "wx/iconbndl.h" +#include "wx/bmpbndl.h" class WXDLLIMPEXP_FWD_CORE wxArtProvidersList; class WXDLLIMPEXP_FWD_CORE wxArtProviderCache; @@ -157,6 +158,14 @@ public: const wxArtClient& client = wxASCII_STR(wxART_OTHER), const wxSize& size = wxDefaultSize); + // Query the providers for bitmapbundle with given ID and return it. + // If none is available, then the search for a bitmap with the same properties + // is performed. If successful, the bitmap is wrapped into a bitmap bundle. + static wxBitmapBundle + GetBitmapBundle(const wxArtID& id, + const wxArtClient& client = wxASCII_STR(wxART_OTHER), + const wxSize& size = wxDefaultSize); + // Query the providers for icon with given ID and return it. Return // wxNullIcon if no provider provides it. static wxIcon GetIcon(const wxArtID& id, @@ -225,6 +234,15 @@ protected: return wxNullBitmap; } + // Derived classes must override CreateBitmapBundle if they provide + // a bundle that cannot be represented through an ordinary bitmap. + virtual wxBitmapBundle CreateBitmapBundle(const wxArtID& id, + const wxArtClient& client, + const wxSize& size) + { + return wxBitmapBundle(CreateBitmap(id, client, size)); + } + virtual wxIconBundle CreateIconBundle(const wxArtID& WXUNUSED(id), const wxArtClient& WXUNUSED(client)) { diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index 4e29fb6291..c00166e1ae 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -44,7 +44,7 @@ WX_NSImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromIconRef( WXHICON iconref ); WX_NSImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromCFURL( CFURLRef urlref ); WX_NSImage WXDLLIMPEXP_CORE wxOSXGetIconForType(OSType type ); void WXDLLIMPEXP_CORE wxOSXSetImageSize(WX_NSImage image, CGFloat width, CGFloat height); -wxBitmap WXDLLIMPEXP_CORE wxOSXCreateSystemBitmap(const wxString& id, const wxString &client, const wxSize& size); +wxBitmapBundle WXDLLIMPEXP_CORE wxOSXCreateSystemBitmapBundle(const wxString& id, const wxString &client, const wxSize& size); WXWindow WXDLLIMPEXP_CORE wxOSXGetMainWindow(); WXWindow WXDLLIMPEXP_CORE wxOSXGetKeyWindow(); WXImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromNSCursor(const WXHCURSOR cursor); diff --git a/include/wx/osx/iphone/private.h b/include/wx/osx/iphone/private.h index 0bb8939514..1acf0dd175 100644 --- a/include/wx/osx/iphone/private.h +++ b/include/wx/osx/iphone/private.h @@ -34,7 +34,7 @@ OSStatus WXDLLIMPEXP_CORE wxMacDrawCGImage( CGImageRef inImage) ; WX_UIImage WXDLLIMPEXP_CORE wxOSXGetUIImageFromCGImage( CGImageRef image ); -wxBitmap WXDLLIMPEXP_CORE wxOSXCreateSystemBitmap(const wxString& id, const wxString &client, const wxSize& size); +wxBitmapBundle WXDLLIMPEXP_CORE wxOSXCreateSystemBitmapBundle(const wxString& id, const wxString &client, const wxSize& size); class WXDLLIMPEXP_CORE wxWidgetIPhoneImpl : public wxWidgetImpl { diff --git a/interface/wx/artprov.h b/interface/wx/artprov.h index 260f61d218..95df55859f 100644 --- a/interface/wx/artprov.h +++ b/interface/wx/artprov.h @@ -110,13 +110,21 @@ const char* wxART_EDIT; class MyProvider : public wxArtProvider { protected: + // Override this method to return a bundle containing the required + // bitmap in all available sizes. + wxBitmapBundle CreateBitmapBundle(const wxArtID& id, + const wxArtClient& client, + const wxSize& size) override; + + // If all bitmaps are available in a single size only, it may be + // simpler to override just this one. wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client, - const wxSize& size); + const wxSize& size) override; // optionally override this one as well wxIconBundle CreateIconBundle(const wxArtID& id, - const wxArtClient& client); + const wxArtClient& client) override; { ... } }; ... @@ -128,8 +136,8 @@ const char* wxART_EDIT; and supplying icon bundles that contain different bitmap sizes. There's another way of taking advantage of this class: you can use it in your - code and use platform native icons as provided by wxArtProvider::GetBitmap or - wxArtProvider::GetIcon. + code and use platform native icons as provided by wxArtProvider::GetBitmapBundle + or wxArtProvider::GetIcon. @section artprovider_identify Identifying art resources @@ -272,6 +280,9 @@ public: /** Query registered providers for bitmap with given ID. + Note that applications using wxWidgets 3.1.6 or later should prefer + calling GetBitmapBundle(). + @param id wxArtID unique identifier of the bitmap. @param client @@ -286,6 +297,28 @@ public: const wxArtClient& client = wxART_OTHER, const wxSize& size = wxDefaultSize); + /** + Query registered providers for a bundle of bitmaps with given ID. + + @since 3.1.6 + + @param id + wxArtID unique identifier of the bitmap. + @param client + wxArtClient identifier of the client (i.e. who is asking for the bitmap). + @param size + Default size for the returned bundle. + + @return If any of the registered providers recognizes the ID in its + CreateBitmapBundle(), this bundle is returned. Otherwise, if any of + providers returns a valid bitmap from CreateBitmap(), the bundle + containing only this bitmap is returned. Otherwise, an empty bundle + is returned. + */ + static wxBitmapBundle GetBitmapBundle(const wxArtID& id, + const wxArtClient& client = wxART_OTHER, + const wxSize& size = wxDefaultSize); + /** Same as wxArtProvider::GetBitmap, but return a wxIcon object (or ::wxNullIcon on failure). @@ -404,8 +437,13 @@ public: protected: /** - Derived art provider classes must override this method to create requested art - resource. Note that returned bitmaps are cached by wxArtProvider and it is + Derived art provider classes may override this method to create requested art + resource. + + For bitmaps available in more than one size, CreateBitmapBundle() + should be overridden instead. + + Note that returned bitmaps are cached by wxArtProvider and it is therefore not necessary to optimize CreateBitmap() for speed (e.g. you may create wxBitmap objects from XPMs here). @@ -429,6 +467,29 @@ protected: const wxArtClient& client, const wxSize& size); + /** + Override this method to create the requested art resources available in + more than one size. + + Unlike CreateBitmap(), this method can be overridden to return the same + bitmap in several (or all, if wxBitmapBundle::FromSVG() is used) sizes + at once, which will allow selecting the size best suited for the + current display resolution automatically. + + @param id + wxArtID unique identifier of the bitmap. + @param client + wxArtClient identifier of the client (i.e. who is asking for the bitmap). + This only serves as a hint. + @param size + Default size of the bitmaps returned by the bundle. + + @since 3.1.6 + */ + virtual wxBitmapBundle CreateBitmapBundle(const wxArtID& id, + const wxArtClient& client, + const wxSize& size); + /** This method is similar to CreateBitmap() but can be used when a bitmap (or an icon) exists in several sizes. diff --git a/src/common/artprov.cpp b/src/common/artprov.cpp index 07d662dacc..66327070fb 100644 --- a/src/common/artprov.cpp +++ b/src/common/artprov.cpp @@ -39,6 +39,7 @@ WX_DEFINE_LIST(wxArtProvidersList) // ---------------------------------------------------------------------------- WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap, wxArtProviderBitmapsHash); +WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmapBundle, wxArtProviderBitmapBundlesHash); WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle, wxArtProviderIconBundlesHash); class WXDLLEXPORT wxArtProviderCache @@ -48,6 +49,10 @@ public: void PutBitmap(const wxString& full_id, const wxBitmap& bmp) { m_bitmapsHash[full_id] = bmp; } + bool GetBitmapBundle(const wxString& full_id, wxBitmapBundle* bmpbndl); + void PutBitmapBundle(const wxString& full_id, const wxBitmapBundle& bmpbndl) + { m_bitmapsBundlesHash[full_id] = bmpbndl; } + bool GetIconBundle(const wxString& full_id, wxIconBundle* bmp); void PutIconBundle(const wxString& full_id, const wxIconBundle& iconbundle) { m_iconBundlesHash[full_id] = iconbundle; } @@ -62,8 +67,9 @@ public: const wxArtClient& client); private: - wxArtProviderBitmapsHash m_bitmapsHash; // cache of wxBitmaps - wxArtProviderIconBundlesHash m_iconBundlesHash; // cache of wxIconBundles + wxArtProviderBitmapsHash m_bitmapsHash; // cache of wxBitmaps + wxArtProviderBitmapBundlesHash m_bitmapsBundlesHash; // cache of wxBitmaps + wxArtProviderIconBundlesHash m_iconBundlesHash; // cache of wxIconBundles }; bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) @@ -80,6 +86,21 @@ bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) } } +bool wxArtProviderCache::GetBitmapBundle(const wxString& full_id, wxBitmapBundle* bmpbndl) +{ + wxArtProviderBitmapBundlesHash::iterator entry = m_bitmapsBundlesHash.find(full_id); + if ( entry == m_bitmapsBundlesHash.end() ) + { + return false; + } + else + { + *bmpbndl = entry->second; + return true; + } +} + + bool wxArtProviderCache::GetIconBundle(const wxString& full_id, wxIconBundle* bmp) { wxArtProviderIconBundlesHash::iterator entry = m_iconBundlesHash.find(full_id); @@ -274,6 +295,37 @@ void wxArtProvider::RescaleBitmap(wxBitmap& bmp, const wxSize& sizeNeeded) return bmp; } +/*static*/ +wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id, + const wxArtClient& client, + const wxSize& size) +{ + // safety-check against writing client,id,size instead of id,client,size: + wxASSERT_MSG( client.Last() == wxT('C'), wxT("invalid 'client' parameter") ); + + wxCHECK_MSG( sm_providers, wxNullBitmap, wxT("no wxArtProvider exists") ); + + wxString hashId = wxArtProviderCache::ConstructHashID(id, client); + + wxBitmapBundle bitmapbundle; // (DoGetIconBundle(id, client)); + + if ( !sm_cache->GetBitmapBundle(hashId, &bitmapbundle) ) + { + for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); + node; node = node->GetNext()) + { + bitmapbundle = node->GetData()->CreateBitmapBundle(id, client, size); + if ( bitmapbundle.IsOk() ) + break; + } + + sm_cache->PutBitmapBundle(hashId, bitmapbundle); + } + + return bitmapbundle; +} + + /*static*/ wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client) { diff --git a/src/osx/artmac.cpp b/src/osx/artmac.cpp index fda7bd5658..81faccb758 100644 --- a/src/osx/artmac.cpp +++ b/src/osx/artmac.cpp @@ -35,11 +35,11 @@ protected: const wxArtClient& client) wxOVERRIDE; #endif #if wxOSX_USE_COCOA_OR_IPHONE - virtual wxBitmap CreateBitmap(const wxArtID& id, + virtual wxBitmapBundle CreateBitmapBundle(const wxArtID& id, const wxArtClient& client, const wxSize& size) wxOVERRIDE { - return wxOSXCreateSystemBitmap(id, client, size); + return wxOSXCreateSystemBitmapBundle(id, client, size); } #endif }; diff --git a/src/osx/carbon/utilscocoa.mm b/src/osx/carbon/utilscocoa.mm index 7e27bb21ac..4dbf4848e8 100644 --- a/src/osx/carbon/utilscocoa.mm +++ b/src/osx/carbon/utilscocoa.mm @@ -27,6 +27,7 @@ #endif #include "wx/fontutil.h" +#include "wx/private/bmpbndl.h" #ifdef __WXMAC__ @@ -165,14 +166,14 @@ WXWindow wxOSXGetKeyWindow() #if wxOSX_USE_IPHONE -wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &client, const wxSize& size) +wxBitmapBundle wxOSXCreateSystemBitmapBundle(const wxString& name, const wxString &client, const wxSize& size) { #if 1 // unfortunately this only accesses images in the app bundle, not the system wide globals wxCFStringRef cfname(name); - return wxBitmap( [[UIImage imageNamed:cfname.AsNSString()] CGImage] ); + return wxOSXMakeBundleFromImage( [UIImage imageNamed:cfname.AsNSString()] ); #else - return wxBitmap(); + return wxNullBitmap; #endif } @@ -197,14 +198,12 @@ WXImage wxOSXGetSystemImage(const wxString& name) return nsimage; } -wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &WXUNUSED(client), const wxSize& WXUNUSED(sizeHint)) +wxBitmapBundle wxOSXCreateSystemBitmapBundle(const wxString& name, const wxString &WXUNUSED(client), const wxSize& WXUNUSED(sizeHint)) { NSImage* nsimage = wxOSXGetSystemImage(name); if ( nsimage ) { - // if ( sizeHint != wxDefaultSize ) - // [nsimage setSize:NSMakeSize(sizeHint.GetHeight(), sizeHint.GetWidth())]; - return wxBitmap( nsimage ); + return wxOSXMakeBundleFromImage( nsimage ); } return wxNullBitmap; }