1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/artprov.cpp
3 // Purpose: wxArtProvider class
4 // Author: Vaclav Slavik
7 // Copyright: (c) Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ---------------------------------------------------------------------------
13 // ---------------------------------------------------------------------------
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
18 #if defined(__BORLANDC__)
22 #include "wx/artprov.h"
27 #include "wx/hashmap.h"
29 #include "wx/module.h"
32 // ===========================================================================
34 // ===========================================================================
36 #include "wx/listimpl.cpp"
37 WX_DECLARE_LIST(wxArtProvider
, wxArtProvidersList
);
38 WX_DEFINE_LIST(wxArtProvidersList
)
40 // ----------------------------------------------------------------------------
41 // Cache class - stores already requested bitmaps
42 // ----------------------------------------------------------------------------
44 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap
, wxArtProviderBitmapsHash
);
45 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle
, wxArtProviderIconBundlesHash
);
47 class WXDLLEXPORT wxArtProviderCache
50 bool GetBitmap(const wxString
& full_id
, wxBitmap
* bmp
);
51 void PutBitmap(const wxString
& full_id
, const wxBitmap
& bmp
)
52 { m_bitmapsHash
[full_id
] = bmp
; }
54 bool GetIconBundle(const wxString
& full_id
, wxIconBundle
* bmp
);
55 void PutIconBundle(const wxString
& full_id
, const wxIconBundle
& iconbundle
)
56 { m_iconBundlesHash
[full_id
] = iconbundle
; }
60 static wxString
ConstructHashID(const wxArtID
& id
,
61 const wxArtClient
& client
,
64 static wxString
ConstructHashID(const wxArtID
& id
,
65 const wxArtClient
& client
);
68 wxArtProviderBitmapsHash m_bitmapsHash
; // cache of wxBitmaps
69 wxArtProviderIconBundlesHash m_iconBundlesHash
; // cache of wxIconBundles
72 bool wxArtProviderCache::GetBitmap(const wxString
& full_id
, wxBitmap
* bmp
)
74 wxArtProviderBitmapsHash::iterator entry
= m_bitmapsHash
.find(full_id
);
75 if ( entry
== m_bitmapsHash
.end() )
86 bool wxArtProviderCache::GetIconBundle(const wxString
& full_id
, wxIconBundle
* bmp
)
88 wxArtProviderIconBundlesHash::iterator entry
= m_iconBundlesHash
.find(full_id
);
89 if ( entry
== m_iconBundlesHash
.end() )
100 void wxArtProviderCache::Clear()
102 m_bitmapsHash
.clear();
103 m_iconBundlesHash
.clear();
106 /* static */ wxString
107 wxArtProviderCache::ConstructHashID(const wxArtID
& id
,
108 const wxArtClient
& client
)
110 return id
+ wxT('-') + client
;
114 /* static */ wxString
115 wxArtProviderCache::ConstructHashID(const wxArtID
& id
,
116 const wxArtClient
& client
,
119 return ConstructHashID(id
, client
) + wxT('-') +
120 wxString::Format(wxT("%d-%d"), size
.x
, size
.y
);
123 // ============================================================================
124 // wxArtProvider class
125 // ============================================================================
127 IMPLEMENT_ABSTRACT_CLASS(wxArtProvider
, wxObject
)
129 wxArtProvidersList
*wxArtProvider::sm_providers
= NULL
;
130 wxArtProviderCache
*wxArtProvider::sm_cache
= NULL
;
132 // ----------------------------------------------------------------------------
133 // wxArtProvider ctors/dtor
134 // ----------------------------------------------------------------------------
136 wxArtProvider::~wxArtProvider()
141 // ----------------------------------------------------------------------------
142 // wxArtProvider operations on provider stack
143 // ----------------------------------------------------------------------------
145 /*static*/ void wxArtProvider::CommonAddingProvider()
149 sm_providers
= new wxArtProvidersList
;
150 sm_cache
= new wxArtProviderCache
;
156 /*static*/ void wxArtProvider::Push(wxArtProvider
*provider
)
158 CommonAddingProvider();
159 sm_providers
->Insert(provider
);
162 /*static*/ void wxArtProvider::PushBack(wxArtProvider
*provider
)
164 CommonAddingProvider();
165 sm_providers
->Append(provider
);
168 /*static*/ bool wxArtProvider::Pop()
170 wxCHECK_MSG( sm_providers
, false, wxT("no wxArtProvider exists") );
171 wxCHECK_MSG( !sm_providers
->empty(), false, wxT("wxArtProviders stack is empty") );
173 delete sm_providers
->GetFirst()->GetData();
178 /*static*/ bool wxArtProvider::Remove(wxArtProvider
*provider
)
180 wxCHECK_MSG( sm_providers
, false, wxT("no wxArtProvider exists") );
182 if ( sm_providers
->DeleteObject(provider
) )
191 /*static*/ bool wxArtProvider::Delete(wxArtProvider
*provider
)
193 // provider will remove itself from the stack in its dtor
199 /*static*/ void wxArtProvider::CleanUpProviders()
203 while ( !sm_providers
->empty() )
204 delete *sm_providers
->begin();
206 wxDELETE(sm_providers
);
211 // ----------------------------------------------------------------------------
212 // wxArtProvider: retrieving bitmaps/icons
213 // ----------------------------------------------------------------------------
215 /*static*/ wxBitmap
wxArtProvider::GetBitmap(const wxArtID
& id
,
216 const wxArtClient
& client
,
219 // safety-check against writing client,id,size instead of id,client,size:
220 wxASSERT_MSG( client
.Last() == wxT('C'), wxT("invalid 'client' parameter") );
222 wxCHECK_MSG( sm_providers
, wxNullBitmap
, wxT("no wxArtProvider exists") );
224 wxString hashId
= wxArtProviderCache::ConstructHashID(id
, client
, size
);
227 if ( !sm_cache
->GetBitmap(hashId
, &bmp
) )
229 for (wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
230 node
; node
= node
->GetNext())
232 bmp
= node
->GetData()->CreateBitmap(id
, client
, size
);
237 wxSize sizeNeeded
= size
;
240 // no bitmap created -- as a fallback, try if we can find desired
242 wxIconBundle iconBundle
= DoGetIconBundle(id
, client
);
243 if ( iconBundle
.IsOk() )
245 if ( sizeNeeded
== wxDefaultSize
)
246 sizeNeeded
= GetNativeSizeHint(client
);
248 wxIcon
icon(iconBundle
.GetIcon(sizeNeeded
));
251 // this icon may be not of the correct size, it will be
252 // rescaled below in such case
253 bmp
.CopyFromIcon(icon
);
258 // if we didn't get the correct size, resize the bitmap
259 #if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
260 if ( bmp
.IsOk() && sizeNeeded
!= wxDefaultSize
)
262 if ( bmp
.GetSize() != sizeNeeded
)
264 wxImage img
= bmp
.ConvertToImage();
265 img
.Rescale(sizeNeeded
.x
, sizeNeeded
.y
);
269 #endif // wxUSE_IMAGE
271 sm_cache
->PutBitmap(hashId
, bmp
);
278 wxIconBundle
wxArtProvider::GetIconBundle(const wxArtID
& id
, const wxArtClient
& client
)
280 wxIconBundle
iconbundle(DoGetIconBundle(id
, client
));
282 if ( iconbundle
.IsOk() )
288 // fall back to single-icon bundle
289 return wxIconBundle(GetIcon(id
, client
));
294 wxIconBundle
wxArtProvider::DoGetIconBundle(const wxArtID
& id
, const wxArtClient
& client
)
296 // safety-check against writing client,id,size instead of id,client,size:
297 wxASSERT_MSG( client
.Last() == wxT('C'), wxT("invalid 'client' parameter") );
299 wxCHECK_MSG( sm_providers
, wxNullIconBundle
, wxT("no wxArtProvider exists") );
301 wxString hashId
= wxArtProviderCache::ConstructHashID(id
, client
);
303 wxIconBundle iconbundle
;
304 if ( !sm_cache
->GetIconBundle(hashId
, &iconbundle
) )
306 for (wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
307 node
; node
= node
->GetNext())
309 iconbundle
= node
->GetData()->CreateIconBundle(id
, client
);
310 if ( iconbundle
.IsOk() )
314 sm_cache
->PutIconBundle(hashId
, iconbundle
);
320 /*static*/ wxIcon
wxArtProvider::GetIcon(const wxArtID
& id
,
321 const wxArtClient
& client
,
324 wxBitmap bmp
= GetBitmap(id
, client
, size
);
330 icon
.CopyFromBitmap(bmp
);
335 wxArtID
wxArtProvider::GetMessageBoxIconId(int flags
)
337 switch ( flags
& wxICON_MASK
)
340 wxFAIL_MSG(wxT("incorrect message box icon flags"));
346 case wxICON_INFORMATION
:
347 return wxART_INFORMATION
;
350 return wxART_WARNING
;
352 case wxICON_QUESTION
:
353 return wxART_QUESTION
;
357 /*static*/ wxSize
wxArtProvider::GetSizeHint(const wxArtClient
& client
,
358 bool platform_dependent
)
360 if (!platform_dependent
)
362 wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
364 return node
->GetData()->DoGetSizeHint(client
);
367 return GetNativeSizeHint(client
);
370 #ifndef wxHAS_NATIVE_ART_PROVIDER_IMPL
372 wxSize
wxArtProvider::GetNativeSizeHint(const wxArtClient
& WXUNUSED(client
))
374 // rather than returning some arbitrary value that doesn't make much
375 // sense (as 2.8 used to do), tell the caller that we don't have a clue:
376 return wxDefaultSize
;
380 void wxArtProvider::InitNativeProvider()
383 #endif // !wxHAS_NATIVE_ART_PROVIDER_IMPL
387 bool wxArtProvider::HasNativeProvider()
396 // ----------------------------------------------------------------------------
397 // deprecated wxArtProvider methods
398 // ----------------------------------------------------------------------------
400 #if WXWIN_COMPATIBILITY_2_6
402 /* static */ void wxArtProvider::PushProvider(wxArtProvider
*provider
)
407 /* static */ void wxArtProvider::InsertProvider(wxArtProvider
*provider
)
412 /* static */ bool wxArtProvider::PopProvider()
417 /* static */ bool wxArtProvider::RemoveProvider(wxArtProvider
*provider
)
419 // RemoveProvider() used to delete the provider being removed so this is
420 // not a typo, we must call Delete() and not Remove() here
421 return Delete(provider
);
424 #endif // WXWIN_COMPATIBILITY_2_6
426 #if WXWIN_COMPATIBILITY_2_8
427 /* static */ void wxArtProvider::Insert(wxArtProvider
*provider
)
431 #endif // WXWIN_COMPATIBILITY_2_8
433 // ============================================================================
434 // wxArtProviderModule
435 // ============================================================================
437 class wxArtProviderModule
: public wxModule
442 // The order here is such that the native provider will be used first
443 // and the standard one last as all these default providers add
444 // themselves to the bottom of the stack.
445 wxArtProvider::InitNativeProvider();
446 #if wxUSE_ARTPROVIDER_TANGO
447 wxArtProvider::InitTangoProvider();
448 #endif // wxUSE_ARTPROVIDER_TANGO
449 #if wxUSE_ARTPROVIDER_STD
450 wxArtProvider::InitStdProvider();
451 #endif // wxUSE_ARTPROVIDER_STD
456 wxArtProvider::CleanUpProviders();
459 DECLARE_DYNAMIC_CLASS(wxArtProviderModule
)
462 IMPLEMENT_DYNAMIC_CLASS(wxArtProviderModule
, wxModule
)