1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/common/artprov.cpp
3
// Purpose: wxArtProvider class
4
// Author: Vaclav Slavik
7
// RCS-ID: $Id: artprov.cpp 70154 2011-12-28 13:51:29Z VZ $
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
// The order here is such that the native provider will be used first
444
// and the standard one last as all these default providers add
445
// themselves to the bottom of the stack.
446
wxArtProvider::InitNativeProvider();
447
#if wxUSE_ARTPROVIDER_TANGO
448
wxArtProvider::InitTangoProvider();
449
#endif // wxUSE_ARTPROVIDER_TANGO
450
#if wxUSE_ARTPROVIDER_STD
451
wxArtProvider::InitStdProvider();
452
#endif // wxUSE_ARTPROVIDER_STD
457
wxArtProvider::CleanUpProviders();
460
DECLARE_DYNAMIC_CLASS(wxArtProviderModule)
463
IMPLEMENT_DYNAMIC_CLASS(wxArtProviderModule, wxModule)