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();
215 // ----------------------------------------------------------------------------
216 // wxArtProvider: retrieving bitmaps/icons
217 // ----------------------------------------------------------------------------
219 /*static*/ wxBitmap
wxArtProvider::GetBitmap(const wxArtID
& id
,
220 const wxArtClient
& client
,
223 // safety-check against writing client,id,size instead of id,client,size:
224 wxASSERT_MSG( client
.Last() == wxT('C'), wxT("invalid 'client' parameter") );
226 wxCHECK_MSG( sm_providers
, wxNullBitmap
, wxT("no wxArtProvider exists") );
228 wxString hashId
= wxArtProviderCache::ConstructHashID(id
, client
, size
);
231 if ( !sm_cache
->GetBitmap(hashId
, &bmp
) )
233 for (wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
234 node
; node
= node
->GetNext())
236 bmp
= node
->GetData()->CreateBitmap(id
, client
, size
);
243 // no bitmap created -- as a fallback, try if we can find desired
245 wxIconBundle iconBundle
= DoGetIconBundle(id
, client
);
246 if ( iconBundle
.IsOk() )
248 wxSize
sz(size
!= wxDefaultSize
250 : GetNativeSizeHint(client
));
251 wxIcon
icon(iconBundle
.GetIcon(sz
));
253 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 ( size
!= wxDefaultSize
&&
262 (bmp
.GetWidth() != size
.x
|| bmp
.GetHeight() != size
.y
) )
264 wxImage img
= bmp
.ConvertToImage();
265 img
.Rescale(size
.x
, size
.y
);
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 wxIcon
wxArtProvider::GetMessageBoxIcon(int flags
)
338 switch ( flags
& wxICON_MASK
)
341 wxFAIL_MSG(wxT("incorrect message box icon flags"));
345 icon
= wxArtProvider::GetIcon(wxART_ERROR
, wxART_MESSAGE_BOX
);
348 case wxICON_INFORMATION
:
349 icon
= wxArtProvider::GetIcon(wxART_INFORMATION
, wxART_MESSAGE_BOX
);
353 icon
= wxArtProvider::GetIcon(wxART_WARNING
, wxART_MESSAGE_BOX
);
356 case wxICON_QUESTION
:
357 icon
= wxArtProvider::GetIcon(wxART_QUESTION
, wxART_MESSAGE_BOX
);
364 /*static*/ wxSize
wxArtProvider::GetSizeHint(const wxArtClient
& client
,
365 bool platform_dependent
)
367 if (!platform_dependent
)
369 wxArtProvidersList::compatibility_iterator node
= sm_providers
->GetFirst();
371 return node
->GetData()->DoGetSizeHint(client
);
374 return GetNativeSizeHint(client
);
377 #ifndef wxHAS_NATIVE_ART_PROVIDER_IMPL
379 wxSize
wxArtProvider::GetNativeSizeHint(const wxArtClient
& WXUNUSED(client
))
381 // rather than returning some arbitrary value that doesn't make much
382 // sense (as 2.8 used to do), tell the caller that we don't have a clue:
383 return wxDefaultSize
;
387 void wxArtProvider::InitNativeProvider()
390 #endif // !wxHAS_NATIVE_ART_PROVIDER_IMPL
394 bool wxArtProvider::HasNativeProvider()
403 // ----------------------------------------------------------------------------
404 // deprecated wxArtProvider methods
405 // ----------------------------------------------------------------------------
407 #if WXWIN_COMPATIBILITY_2_6
409 /* static */ void wxArtProvider::PushProvider(wxArtProvider
*provider
)
414 /* static */ void wxArtProvider::InsertProvider(wxArtProvider
*provider
)
419 /* static */ bool wxArtProvider::PopProvider()
424 /* static */ bool wxArtProvider::RemoveProvider(wxArtProvider
*provider
)
426 // RemoveProvider() used to delete the provider being removed so this is
427 // not a typo, we must call Delete() and not Remove() here
428 return Delete(provider
);
431 #endif // WXWIN_COMPATIBILITY_2_6
433 #if WXWIN_COMPATIBILITY_2_8
434 /* static */ void wxArtProvider::Insert(wxArtProvider
*provider
)
438 #endif // WXWIN_COMPATIBILITY_2_8
440 // ============================================================================
441 // wxArtProviderModule
442 // ============================================================================
444 class wxArtProviderModule
: public wxModule
449 wxArtProvider::InitStdProvider();
450 wxArtProvider::InitNativeProvider();
455 wxArtProvider::CleanUpProviders();
458 DECLARE_DYNAMIC_CLASS(wxArtProviderModule
)
461 IMPLEMENT_DYNAMIC_CLASS(wxArtProviderModule
, wxModule
)