1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/artprov.cpp
3 // Purpose: wxArtProvider class
4 // Author: Vaclav Slavik
8 // Copyright: (c) Vaclav Slavik
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ---------------------------------------------------------------------------
14 // ---------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #if defined(__BORLANDC__)
23 #include "wx/artprov.h"
28 #include "wx/hashmap.h"
30 #include "wx/module.h"
33 // ===========================================================================
35 // ===========================================================================
37 #include "wx/listimpl.cpp"
38 WX_DECLARE_LIST(wxArtProvider
, wxArtProvidersList
);
39 WX_DEFINE_LIST(wxArtProvidersList
)
41 // ----------------------------------------------------------------------------
42 // Cache class - stores already requested bitmaps
43 // ----------------------------------------------------------------------------
45 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap
, wxArtProviderBitmapsHash
);
46 WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle
, wxArtProviderIconBundlesHash
);
48 class WXDLLEXPORT wxArtProviderCache
51 bool GetBitmap(const wxString
& full_id
, wxBitmap
* bmp
);
52 void PutBitmap(const wxString
& full_id
, const wxBitmap
& bmp
)
53 { m_bitmapsHash
[full_id
] = bmp
; }
55 bool GetIconBundle(const wxString
& full_id
, wxIconBundle
* bmp
);
56 void PutIconBundle(const wxString
& full_id
, const wxIconBundle
& iconbundle
)
57 { m_iconBundlesHash
[full_id
] = iconbundle
; }
61 static wxString
ConstructHashID(const wxArtID
& id
,
62 const wxArtClient
& client
,
65 static wxString
ConstructHashID(const wxArtID
& id
,
66 const wxArtClient
& client
);
69 wxArtProviderBitmapsHash m_bitmapsHash
; // cache of wxBitmaps
70 wxArtProviderIconBundlesHash m_iconBundlesHash
; // cache of wxIconBundles
73 bool wxArtProviderCache::GetBitmap(const wxString
& full_id
, wxBitmap
* bmp
)
75 wxArtProviderBitmapsHash::iterator entry
= m_bitmapsHash
.find(full_id
);
76 if ( entry
== m_bitmapsHash
.end() )
87 bool wxArtProviderCache::GetIconBundle(const wxString
& full_id
, wxIconBundle
* bmp
)
89 wxArtProviderIconBundlesHash::iterator entry
= m_iconBundlesHash
.find(full_id
);
90 if ( entry
== m_iconBundlesHash
.end() )
101 void wxArtProviderCache::Clear()
103 m_bitmapsHash
.clear();
104 m_iconBundlesHash
.clear();
107 /* static */ wxString
108 wxArtProviderCache::ConstructHashID(const wxArtID
& id
,
109 const wxArtClient
& client
)
111 return id
+ wxT('-') + client
;
115 /* static */ wxString
116 wxArtProviderCache::ConstructHashID(const wxArtID
& id
,
117 const wxArtClient
& client
,
120 return ConstructHashID(id
, client
) + wxT('-') +
121 wxString::Format(wxT("%d-%d"), size
.x
, size
.y
);
124 // ============================================================================
125 // wxArtProvider class
126 // ============================================================================
128 IMPLEMENT_ABSTRACT_CLASS(wxArtProvider
, wxObject
)
130 wxArtProvidersList
*wxArtProvider::sm_providers
= NULL
;
131 wxArtProviderCache
*wxArtProvider::sm_cache
= NULL
;
133 // ----------------------------------------------------------------------------
134 // wxArtProvider ctors/dtor
135 // ----------------------------------------------------------------------------
137 wxArtProvider::~wxArtProvider()
142 // ----------------------------------------------------------------------------
143 // wxArtProvider operations on provider stack
144 // ----------------------------------------------------------------------------
146 /*static*/ void wxArtProvider::CommonAddingProvider()
150 sm_providers
= new wxArtProvidersList
;
151 sm_cache
= new wxArtProviderCache
;
157 /*static*/ void wxArtProvider::Push(wxArtProvider
*provider
)
159 CommonAddingProvider();
160 sm_providers
->Insert(provider
);
163 /*static*/ void wxArtProvider::PushBack(wxArtProvider
*provider
)
165 CommonAddingProvider();
166 sm_providers
->Append(provider
);
169 /*static*/ bool wxArtProvider::Pop()
171 wxCHECK_MSG( sm_providers
, false, wxT("no wxArtProvider exists") );
172 wxCHECK_MSG( !sm_providers
->empty(), false, wxT("wxArtProviders stack is empty") );
174 delete sm_providers
->GetFirst()->GetData();
179 /*static*/ bool wxArtProvider::Remove(wxArtProvider
*provider
)
181 wxCHECK_MSG( sm_providers
, false, wxT("no wxArtProvider exists") );
183 if ( sm_providers
->DeleteObject(provider
) )
192 /*static*/ bool wxArtProvider::Delete(wxArtProvider
*provider
)
194 // provider will remove itself from the stack in its dtor
200 /*static*/ void wxArtProvider::CleanUpProviders()
204 while ( !sm_providers
->empty() )
205 delete *sm_providers
->begin();
207 wxDELETE(sm_providers
);
212 // ----------------------------------------------------------------------------
213 // wxArtProvider: retrieving bitmaps/icons
214 // ----------------------------------------------------------------------------
216 /*static*/ wxBitmap
wxArtProvider::GetBitmap(const wxArtID
& id
,
217 const wxArtClient
& client
,
220 // safety-check against writing client,id,size instead of id,client,size:
221 wxASSERT_MSG( client
.Last() == wxT('C'), wxT("invalid 'client' parameter") );
223 wxCHECK_MSG( sm_providers
, wxNullBitmap
, wxT("no wxArtProvider exists") );
225 wxString hashId
= wxArtProviderCache::ConstructHashID(id
, client
, size
);
228 if ( !sm_cache
->GetBitmap(hashId
, &bmp
) )
230 for (wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
231 node
; node
= node
->GetNext())
233 bmp
= node
->GetData()->CreateBitmap(id
, client
, size
);
238 wxSize sizeNeeded
= size
;
241 // no bitmap created -- as a fallback, try if we can find desired
243 wxIconBundle iconBundle
= DoGetIconBundle(id
, client
);
244 if ( iconBundle
.IsOk() )
246 if ( sizeNeeded
== wxDefaultSize
)
247 sizeNeeded
= GetNativeSizeHint(client
);
249 wxIcon
icon(iconBundle
.GetIcon(sizeNeeded
));
252 // this icon may be not of the correct size, it will be
253 // rescaled below in such case
254 bmp
.CopyFromIcon(icon
);
259 // if we didn't get the correct size, resize the bitmap
260 #if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
261 if ( bmp
.IsOk() && sizeNeeded
!= wxDefaultSize
)
263 if ( bmp
.GetSize() != sizeNeeded
)
265 wxImage img
= bmp
.ConvertToImage();
266 img
.Rescale(sizeNeeded
.x
, sizeNeeded
.y
);
270 #endif // wxUSE_IMAGE
272 sm_cache
->PutBitmap(hashId
, bmp
);
279 wxIconBundle
wxArtProvider::GetIconBundle(const wxArtID
& id
, const wxArtClient
& client
)
281 wxIconBundle
iconbundle(DoGetIconBundle(id
, client
));
283 if ( iconbundle
.IsOk() )
289 // fall back to single-icon bundle
290 return wxIconBundle(GetIcon(id
, client
));
295 wxIconBundle
wxArtProvider::DoGetIconBundle(const wxArtID
& id
, const wxArtClient
& client
)
297 // safety-check against writing client,id,size instead of id,client,size:
298 wxASSERT_MSG( client
.Last() == wxT('C'), wxT("invalid 'client' parameter") );
300 wxCHECK_MSG( sm_providers
, wxNullIconBundle
, wxT("no wxArtProvider exists") );
302 wxString hashId
= wxArtProviderCache::ConstructHashID(id
, client
);
304 wxIconBundle iconbundle
;
305 if ( !sm_cache
->GetIconBundle(hashId
, &iconbundle
) )
307 for (wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
308 node
; node
= node
->GetNext())
310 iconbundle
= node
->GetData()->CreateIconBundle(id
, client
);
311 if ( iconbundle
.IsOk() )
315 sm_cache
->PutIconBundle(hashId
, iconbundle
);
321 /*static*/ wxIcon
wxArtProvider::GetIcon(const wxArtID
& id
,
322 const wxArtClient
& client
,
325 wxBitmap bmp
= GetBitmap(id
, client
, size
);
331 icon
.CopyFromBitmap(bmp
);
336 wxArtID
wxArtProvider::GetMessageBoxIconId(int flags
)
338 switch ( flags
& wxICON_MASK
)
341 wxFAIL_MSG(wxT("incorrect message box icon flags"));
347 case wxICON_INFORMATION
:
348 return wxART_INFORMATION
;
351 return wxART_WARNING
;
353 case wxICON_QUESTION
:
354 return wxART_QUESTION
;
358 /*static*/ wxSize
wxArtProvider::GetSizeHint(const wxArtClient
& client
,
359 bool platform_dependent
)
361 if (!platform_dependent
)
363 wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
365 return node
->GetData()->DoGetSizeHint(client
);
368 return GetNativeSizeHint(client
);
371 #ifndef wxHAS_NATIVE_ART_PROVIDER_IMPL
373 wxSize
wxArtProvider::GetNativeSizeHint(const wxArtClient
& WXUNUSED(client
))
375 // rather than returning some arbitrary value that doesn't make much
376 // sense (as 2.8 used to do), tell the caller that we don't have a clue:
377 return wxDefaultSize
;
381 void wxArtProvider::InitNativeProvider()
384 #endif // !wxHAS_NATIVE_ART_PROVIDER_IMPL
388 bool wxArtProvider::HasNativeProvider()
397 // ----------------------------------------------------------------------------
398 // deprecated wxArtProvider methods
399 // ----------------------------------------------------------------------------
401 #if WXWIN_COMPATIBILITY_2_6
403 /* static */ void wxArtProvider::PushProvider(wxArtProvider
*provider
)
408 /* static */ void wxArtProvider::InsertProvider(wxArtProvider
*provider
)
413 /* static */ bool wxArtProvider::PopProvider()
418 /* static */ bool wxArtProvider::RemoveProvider(wxArtProvider
*provider
)
420 // RemoveProvider() used to delete the provider being removed so this is
421 // not a typo, we must call Delete() and not Remove() here
422 return Delete(provider
);
425 #endif // WXWIN_COMPATIBILITY_2_6
427 #if WXWIN_COMPATIBILITY_2_8
428 /* static */ void wxArtProvider::Insert(wxArtProvider
*provider
)
432 #endif // WXWIN_COMPATIBILITY_2_8
434 // ============================================================================
435 // wxArtProviderModule
436 // ============================================================================
438 class wxArtProviderModule
: public wxModule
443 #if wxUSE_ARTPROVIDER_STD
444 wxArtProvider::InitStdProvider();
445 #endif // wxUSE_ARTPROVIDER_STD
446 #if wxUSE_ARTPROVIDER_TANGO
447 wxArtProvider::InitTangoProvider();
448 #endif // wxUSE_ARTPROVIDER_TANGO
449 wxArtProvider::InitNativeProvider();
454 wxArtProvider::CleanUpProviders();
457 DECLARE_DYNAMIC_CLASS(wxArtProviderModule
)
460 IMPLEMENT_DYNAMIC_CLASS(wxArtProviderModule
, wxModule
)