diff --git a/include/wx/artprov.h b/include/wx/artprov.h index a0448f46b3..e346c95533 100644 --- a/include/wx/artprov.h +++ b/include/wx/artprov.h @@ -17,8 +17,8 @@ #include "wx/iconbndl.h" #include "wx/bmpbndl.h" -class WXDLLIMPEXP_FWD_CORE wxArtProvidersList; -class WXDLLIMPEXP_FWD_CORE wxArtProviderCache; +class wxArtProvidersList; +class wxArtProviderCache; class WXDLLIMPEXP_FWD_CORE wxWindow; class wxArtProviderModule; diff --git a/interface/wx/artprov.h b/interface/wx/artprov.h index 200f919774..eadfcb9d50 100644 --- a/interface/wx/artprov.h +++ b/interface/wx/artprov.h @@ -133,6 +133,10 @@ const char* wxART_WX_LOGO; wxArtProvider::Push(new MyProvider); @endcode + Note that, as usual in wxWidgets API, wxArtProvider takes ownership of the + pointer and will destroy it on program shutdown. In particular, you should + not delete this pointer in your own code. + If you need bitmap images (of the same artwork) that should be displayed at different sizes you should probably consider overriding wxArtProvider::CreateIconBundle and supplying icon bundles that contain different bitmap sizes. @@ -423,6 +427,8 @@ public: Register new art provider and add it to the top of providers stack (i.e. it will be queried as the first provider). + @param provider A valid pointer that becomes owned by wxArtProvider. + @see PushBack() */ static void Push(wxArtProvider* provider); @@ -432,6 +438,8 @@ public: In other words, it will be queried as the last one, after all others, including the default provider. + @param provider A valid pointer that becomes owned by wxArtProvider. + @see Push() @since 2.9.0 diff --git a/src/common/artprov.cpp b/src/common/artprov.cpp index 170f307d19..ac78290bc6 100644 --- a/src/common/artprov.cpp +++ b/src/common/artprov.cpp @@ -27,13 +27,15 @@ #include "wx/window.h" #endif -// =========================================================================== -// implementation -// =========================================================================== +#include +#include -#include "wx/listimpl.cpp" -WX_DECLARE_LIST(wxArtProvider, wxArtProvidersList); -WX_DEFINE_LIST(wxArtProvidersList) +using wxArtProviderPtr = std::unique_ptr; +class wxArtProvidersList : public std::list +{ +public: + using std::list::list; +}; // ---------------------------------------------------------------------------- // Cache class - stores already requested bitmaps @@ -43,7 +45,7 @@ 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 +class wxArtProviderCache { public: bool GetBitmap(const wxString& full_id, wxBitmap* bmp); @@ -241,10 +243,7 @@ wxArtProviderCache *wxArtProvider::sm_cache = nullptr; // wxArtProvider ctors/dtor // ---------------------------------------------------------------------------- -wxArtProvider::~wxArtProvider() -{ - Remove(this); -} +wxArtProvider::~wxArtProvider() = default; // ---------------------------------------------------------------------------- // wxArtProvider operations on provider stack @@ -264,13 +263,13 @@ wxArtProvider::~wxArtProvider() /*static*/ void wxArtProvider::Push(wxArtProvider *provider) { CommonAddingProvider(); - sm_providers->Insert(provider); + sm_providers->push_front(wxArtProviderPtr(provider)); } /*static*/ void wxArtProvider::PushBack(wxArtProvider *provider) { CommonAddingProvider(); - sm_providers->Append(provider); + sm_providers->push_back(wxArtProviderPtr(provider)); } /*static*/ bool wxArtProvider::Pop() @@ -278,7 +277,7 @@ wxArtProvider::~wxArtProvider() wxCHECK_MSG( sm_providers, false, wxT("no wxArtProvider exists") ); wxCHECK_MSG( !sm_providers->empty(), false, wxT("wxArtProviders stack is empty") ); - delete sm_providers->GetFirst()->GetData(); + sm_providers->pop_front(); sm_cache->Clear(); return true; } @@ -287,7 +286,16 @@ wxArtProvider::~wxArtProvider() { wxCHECK_MSG( sm_providers, false, wxT("no wxArtProvider exists") ); - if ( sm_providers->DeleteObject(provider) ) + // Unfortunately remove() doesn't return the number of the removed elements + // until C++20, so check whether it did anything manually. + const auto oldSize = sm_providers->size(); + + sm_providers->remove_if([provider](const wxArtProviderPtr& p) + { + return p.get() == provider; + }); + + if ( sm_providers->size() != oldSize ) { sm_cache->Clear(); return true; @@ -308,9 +316,6 @@ wxArtProvider::~wxArtProvider() { if ( sm_providers ) { - while ( !sm_providers->empty() ) - delete *sm_providers->begin(); - wxDELETE(sm_providers); wxDELETE(sm_cache); } @@ -416,10 +421,8 @@ wxArtProvider::RescaleOrResizeIfNeeded(wxBitmap& bmp, const wxSize& sizeNeeded) wxBitmap bmp; if ( !sm_cache->GetBitmap(hashId, &bmp) ) { - for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); - node; node = node->GetNext()) + for (const auto& provider : *sm_providers) { - wxArtProvider* const provider = node->GetData(); bmp = provider->CreateBitmap(id, client, size); if ( bmp.IsOk() ) break; @@ -481,10 +484,8 @@ wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id, if ( !sm_cache->GetBitmapBundle(hashId, &bitmapbundle) ) { - for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); - node; node = node->GetNext()) + for (const auto& provider : *sm_providers) { - wxArtProvider* const provider = node->GetData(); bitmapbundle = provider->CreateBitmapBundle(id, client, size); if ( bitmapbundle.IsOk() ) break; @@ -546,10 +547,9 @@ wxIconBundle wxArtProvider::DoGetIconBundle(const wxArtID& id, const wxArtClient wxIconBundle iconbundle; if ( !sm_cache->GetIconBundle(hashId, &iconbundle) ) { - for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); - node; node = node->GetNext()) + for (const auto& provider : *sm_providers) { - iconbundle = node->GetData()->CreateIconBundle(id, client); + iconbundle = provider->CreateIconBundle(id, client); if ( iconbundle.IsOk() ) break; } @@ -607,9 +607,8 @@ wxArtID wxArtProvider::GetMessageBoxIconId(int flags) /*static*/ wxSize wxArtProvider::GetDIPSizeHint(const wxArtClient& client) { - wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); - if (node) - return node->GetData()->DoGetSizeHint(client); + if ( !sm_providers->empty() ) + return sm_providers->front()->DoGetSizeHint(client); return GetNativeDIPSizeHint(client); }