X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/571d2e0f232be3f7220c485c7e72eccfb87f2855..8f4745feeb2850f3bebb3af45407e164550d541a:/src/common/artprov.cpp?ds=inline diff --git a/src/common/artprov.cpp b/src/common/artprov.cpp index dd5cdb4bd5..fb19f1ebbf 100644 --- a/src/common/artprov.cpp +++ b/src/common/artprov.cpp @@ -43,6 +43,7 @@ WX_DEFINE_LIST(wxArtProvidersList) // ---------------------------------------------------------------------------- WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap, wxArtProviderBitmapsHash); +WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle, wxArtProviderIconBundlesHash); class WXDLLEXPORT wxArtProviderCache { @@ -51,14 +52,22 @@ public: void PutBitmap(const wxString& full_id, const wxBitmap& bmp) { m_bitmapsHash[full_id] = bmp; } + bool GetIconBundle(const wxString& full_id, wxIconBundle* bmp); + void PutIconBundle(const wxString& full_id, const wxIconBundle& iconbundle) + { m_iconBundlesHash[full_id] = iconbundle; } + void Clear(); static wxString ConstructHashID(const wxArtID& id, const wxArtClient& client, const wxSize& size); + static wxString ConstructHashID(const wxArtID& id, + const wxArtClient& client); + private: - wxArtProviderBitmapsHash m_bitmapsHash; + wxArtProviderBitmapsHash m_bitmapsHash; // cache of wxBitmaps + wxArtProviderIconBundlesHash m_iconBundlesHash; // cache of wxIconBundles }; bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) @@ -75,21 +84,43 @@ bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) } } +bool wxArtProviderCache::GetIconBundle(const wxString& full_id, wxIconBundle* bmp) +{ + wxArtProviderIconBundlesHash::iterator entry = m_iconBundlesHash.find(full_id); + if ( entry == m_iconBundlesHash.end() ) + { + return false; + } + else + { + *bmp = entry->second; + return true; + } +} + void wxArtProviderCache::Clear() { m_bitmapsHash.clear(); + m_iconBundlesHash.clear(); } -/*static*/ wxString wxArtProviderCache::ConstructHashID( - const wxArtID& id, const wxArtClient& client, - const wxSize& size) +/* static */ wxString +wxArtProviderCache::ConstructHashID(const wxArtID& id, + const wxArtClient& client) { - wxString str; - str.Printf(wxT("%s-%s-%i-%i"), id.c_str(), client.c_str(), size.x, size.y); - return str; + return id + _T('-') + client; } +/* static */ wxString +wxArtProviderCache::ConstructHashID(const wxArtID& id, + const wxArtClient& client, + const wxSize& size) +{ + return ConstructHashID(id, client) + _T('-') + + wxString::Format(_T("%d-%d"), size.x, size.y); +} + // ============================================================================ // wxArtProvider class // ============================================================================ @@ -129,7 +160,7 @@ wxArtProvider::~wxArtProvider() sm_providers->Insert(provider); } -/*static*/ void wxArtProvider::Insert(wxArtProvider *provider) +/*static*/ void wxArtProvider::PushBack(wxArtProvider *provider) { CommonAddingProvider(); sm_providers->Append(provider); @@ -204,18 +235,37 @@ wxArtProvider::~wxArtProvider() { bmp = node->GetData()->CreateBitmap(id, client, size); if ( bmp.Ok() ) + break; + } + + if ( !bmp.Ok() ) + { + // no bitmap created -- as a fallback, try if we can find desired + // icon in a bundle + wxIconBundle iconBundle = DoGetIconBundle(id, client); + if ( iconBundle.IsOk() ) { + wxSize sz(size != wxDefaultSize + ? size + : GetNativeSizeHint(client)); + wxIcon icon(iconBundle.GetIcon(sz)); + if ( icon.IsOk() ) + bmp.CopyFromIcon(icon); + } + } + + if ( bmp.IsOk() ) + { + // if we didn't get the correct size, resize the bitmap #if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB) - if ( size != wxDefaultSize && - (bmp.GetWidth() != size.x || bmp.GetHeight() != size.y) ) - { - wxImage img = bmp.ConvertToImage(); - img.Rescale(size.x, size.y); - bmp = wxBitmap(img); - } -#endif - break; + if ( size != wxDefaultSize && + (bmp.GetWidth() != size.x || bmp.GetHeight() != size.y) ) + { + wxImage img = bmp.ConvertToImage(); + img.Rescale(size.x, size.y); + bmp = wxBitmap(img); } +#endif } sm_cache->PutBitmap(hashId, bmp); @@ -224,14 +274,56 @@ wxArtProvider::~wxArtProvider() return bmp; } +/*static*/ +wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client) +{ + wxIconBundle iconbundle(DoGetIconBundle(id, client)); + + if ( iconbundle.IsOk() ) + { + return iconbundle; + } + else + { + // fall back to single-icon bundle + return wxIconBundle(GetIcon(id, client)); + } +} + +/*static*/ +wxIconBundle wxArtProvider::DoGetIconBundle(const wxArtID& id, const wxArtClient& client) +{ + // safety-check against writing client,id,size instead of id,client,size: + wxASSERT_MSG( client.Last() == _T('C'), _T("invalid 'client' parameter") ); + + wxCHECK_MSG( sm_providers, wxNullIconBundle, _T("no wxArtProvider exists") ); + + wxString hashId = wxArtProviderCache::ConstructHashID(id, client); + + wxIconBundle iconbundle; + if ( !sm_cache->GetIconBundle(hashId, &iconbundle) ) + { + for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); + node; node = node->GetNext()) + { + iconbundle = node->GetData()->CreateIconBundle(id, client); + if ( iconbundle.IsOk() ) + break; + } + + sm_cache->PutIconBundle(hashId, iconbundle); + } + + return iconbundle; +} + /*static*/ wxIcon wxArtProvider::GetIcon(const wxArtID& id, const wxArtClient& client, const wxSize& size) { - wxCHECK_MSG( sm_providers, wxNullIcon, _T("no wxArtProvider exists") ); - wxBitmap bmp = GetBitmap(id, client, size); - if ( !bmp.Ok() ) + + if ( !bmp.IsOk() ) return wxNullIcon; wxIcon icon; @@ -239,10 +331,35 @@ wxArtProvider::~wxArtProvider() return icon; } -#if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__) - #include "wx/gtk/private.h" - extern GtkIconSize wxArtClientToIconSize(const wxArtClient& client); -#endif // defined(__WXGTK20__) && !defined(__WXUNIVERSAL__) +/* static */ +wxIcon wxArtProvider::GetMessageBoxIcon(int flags) +{ + wxIcon icon; + switch ( flags & wxICON_MASK ) + { + default: + wxFAIL_MSG(_T("incorrect message box icon flags")); + // fall through + + case wxICON_ERROR: + icon = wxArtProvider::GetIcon(wxART_ERROR, wxART_MESSAGE_BOX); + break; + + case wxICON_INFORMATION: + icon = wxArtProvider::GetIcon(wxART_INFORMATION, wxART_MESSAGE_BOX); + break; + + case wxICON_WARNING: + icon = wxArtProvider::GetIcon(wxART_WARNING, wxART_MESSAGE_BOX); + break; + + case wxICON_QUESTION: + icon = wxArtProvider::GetIcon(wxART_QUESTION, wxART_MESSAGE_BOX); + break; + } + + return icon; +} /*static*/ wxSize wxArtProvider::GetSizeHint(const wxArtClient& client, bool platform_dependent) @@ -254,34 +371,33 @@ wxArtProvider::~wxArtProvider() return node->GetData()->DoGetSizeHint(client); } - // else return platform dependent size - -#if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__) - // Gtk has specific sizes for each client, see artgtk.cpp - GtkIconSize gtk_size = wxArtClientToIconSize(client); - // no size hints for this client - if (gtk_size == GTK_ICON_SIZE_INVALID) - return wxDefaultSize; - gint width, height; - gtk_icon_size_lookup( gtk_size, &width, &height); - return wxSize(width, height); -#else // !GTK+ 2 - // NB: These size hints may have to be adjusted per platform - if (client == wxART_TOOLBAR) - return wxSize(16, 15); - else if (client == wxART_MENU) - return wxSize(16, 15); - else if (client == wxART_FRAME_ICON) - return wxSize(16, 15); - else if (client == wxART_CMN_DIALOG || client == wxART_MESSAGE_BOX) - return wxSize(32, 32); - else if (client == wxART_HELP_BROWSER) - return wxSize(16, 15); - else if (client == wxART_BUTTON) - return wxSize(16, 15); - else // wxART_OTHER or perhaps a user's client, no specified size - return wxDefaultSize; -#endif // GTK+ 2/else + return GetNativeSizeHint(client); +} + +#ifndef wxHAS_NATIVE_ART_PROVIDER_IMPL +/*static*/ +wxSize wxArtProvider::GetNativeSizeHint(const wxArtClient& WXUNUSED(client)) +{ + // rather than returning some arbitrary value that doesn't make much + // sense (as 2.8 used to do), tell the caller that we don't have a clue: + return wxDefaultSize; +} + +/*static*/ +void wxArtProvider::InitNativeProvider() +{ +} +#endif // !wxHAS_NATIVE_ART_PROVIDER_IMPL + + +/* static */ +bool wxArtProvider::HasNativeProvider() +{ +#ifdef __WXGTK20__ + return true; +#else + return false; +#endif } // ---------------------------------------------------------------------------- @@ -314,6 +430,13 @@ wxArtProvider::~wxArtProvider() #endif // WXWIN_COMPATIBILITY_2_6 +#if WXWIN_COMPATIBILITY_2_8 +/* static */ void wxArtProvider::Insert(wxArtProvider *provider) +{ + PushBack(provider); +} +#endif // WXWIN_COMPATIBILITY_2_8 + // ============================================================================ // wxArtProviderModule // ============================================================================