]> git.saurik.com Git - wxWidgets.git/blame - src/common/iconbndl.cpp
don't use invalid wxIconBundles, it results in asserts after recent changes
[wxWidgets.git] / src / common / iconbndl.cpp
CommitLineData
f618020a 1/////////////////////////////////////////////////////////////////////////////
923d28da 2// Name: src/common/iconbndl.cpp
f618020a 3// Purpose: wxIconBundle
52734360 4// Author: Mattia Barbon, Vadim Zeitlin
f618020a
MB
5// Created: 23.03.2002
6// RCS-ID: $Id$
7// Copyright: (c) Mattia barbon
65571936 8// Licence: wxWindows licence
f618020a
MB
9/////////////////////////////////////////////////////////////////////////////
10
52734360
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
f618020a
MB
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
923d28da
WS
26#include "wx/iconbndl.h"
27
f618020a
MB
28#ifndef WX_PRECOMP
29 #include "wx/settings.h"
f618020a
MB
30 #include "wx/icon.h"
31 #include "wx/log.h"
32 #include "wx/intl.h"
ed39ff57 33 #include "wx/bitmap.h"
d5309f58
SC
34 #include "wx/image.h"
35#endif
36
f618020a
MB
37#include "wx/arrimpl.cpp"
38
39WX_DEFINE_OBJARRAY(wxIconArray)
40
52734360
VZ
41IMPLEMENT_DYNAMIC_CLASS(wxIconBundle, wxGDIObject)
42
43#define M_ICONBUNDLEDATA ((wxIconBundleRefData *)m_refData)
44
45// ----------------------------------------------------------------------------
46// wxIconBundleRefData
47// ----------------------------------------------------------------------------
48
49class WXDLLEXPORT wxIconBundleRefData : public wxGDIRefData
50{
51public:
52 // default and copy ctors and assignment operators are ok
53
54protected:
55 wxIconArray m_icons;
56
57 friend class WXDLLEXPORT wxIconBundle;
58};
59
60// ============================================================================
61// wxIconBundle implementation
62// ============================================================================
63
64wxIconBundle::wxIconBundle()
65 : wxGDIObject()
66{
67 m_refData = new wxIconBundleRefData;
68}
69
70wxIconBundle::wxIconBundle(const wxString& file, long type)
71 : wxGDIObject()
f618020a 72{
52734360
VZ
73 m_refData = new wxIconBundleRefData;
74 AddIcon(file, type);
75}
f618020a 76
52734360
VZ
77wxIconBundle::wxIconBundle(const wxIconBundle& icon)
78 : wxGDIObject()
79{
80 Ref(icon);
81}
f618020a 82
52734360
VZ
83wxIconBundle::wxIconBundle(const wxIcon& icon)
84 : wxGDIObject()
85{
86 m_refData = new wxIconBundleRefData;
87 AddIcon(icon);
88}
f618020a 89
52734360
VZ
90wxObjectRefData *wxIconBundle::CreateRefData() const
91{
92 return new wxIconBundleRefData;
93}
94
95wxObjectRefData *wxIconBundle::CloneRefData(const wxObjectRefData *data) const
96{
97 return new wxIconBundleRefData(*wx_static_cast(const wxIconBundleRefData *, data));
f618020a
MB
98}
99
100void wxIconBundle::DeleteIcons()
101{
52734360
VZ
102 wxIconBundleRefData* ref = new wxIconBundleRefData();
103 UnRef();
104 m_refData = ref;
f618020a
MB
105}
106
52734360
VZ
107bool wxIconBundle::IsOk() const
108{
109 return M_ICONBUNDLEDATA && !M_ICONBUNDLEDATA->m_icons.IsEmpty();
110}
111
112void wxIconBundle::AddIcon(const wxString& file, long type)
f618020a 113{
52734360
VZ
114#ifdef __WXMAC__
115 // Deal with standard icons
116 if ( type == wxBITMAP_TYPE_ICON_RESOURCE )
117 {
118 wxIcon tmp(file, type);
119 if (tmp.Ok())
120 {
121 AddIcon(tmp);
122 return;
123 }
124 }
125#endif // __WXMAC__
126
64c288fa 127#if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
f618020a 128 wxImage image;
f618020a 129
52734360
VZ
130 const size_t count = wxImage::GetImageCount( file, type );
131 for ( size_t i = 0; i < count; ++i )
f618020a 132 {
52734360 133 if ( !image.LoadFile( file, type, i ) )
f618020a
MB
134 {
135 wxLogError( _("Failed to load image %d from file '%s'."),
136 i, file.c_str() );
137 continue;
138 }
139
52734360
VZ
140 wxIcon tmp;
141 tmp.CopyFromBitmap(wxBitmap(image));
142 AddIcon(tmp);
f618020a 143 }
52734360
VZ
144#else // !wxUSE_IMAGE
145 wxUnusedVar(file);
146 wxUnusedVar(type);
147#endif // wxUSE_IMAGE/!wxUSE_IMAGE
f618020a
MB
148}
149
52734360 150wxIcon wxIconBundle::GetIcon(const wxSize& size) const
f618020a 151{
52734360 152 wxCHECK_MSG( IsOk(), wxNullIcon, _T("invalid icon bundle") );
2fd85ab3 153
52734360 154 const wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons;
f618020a 155
52734360 156 const size_t count = iconArray.size();
8f696653 157
52734360
VZ
158 // optimize for the common case of icon bundles containing one icon only
159 wxIcon iconBest;
160 switch ( count )
f618020a 161 {
52734360
VZ
162 case 0:
163 // nothing to do, iconBest is already invalid
164 break;
165
166 case 1:
167 iconBest = iconArray[0];
168 break;
169
170 default:
171 // there is more than one icon, find the best match:
172 wxCoord sysX = wxSystemSettings::GetMetric( wxSYS_ICON_X ),
173 sysY = wxSystemSettings::GetMetric( wxSYS_ICON_Y );
174
175 for ( size_t i = 0; i < count; i++ )
176 {
177 const wxIcon& icon = iconArray[i];
178 wxCoord sx = icon.GetWidth(),
179 sy = icon.GetHeight();
180
181 // if we got an icon of exactly the requested size, we're done
182 if ( sx == size.x && sy == size.y )
183 {
184 iconBest = icon;
185 break;
186 }
187
188 // the best icon is by default (arbitrarily) the first one but
189 // if we find a system-sized icon, take it instead
190 if ( sx == sysX && sy == sysY || !iconBest.IsOk() )
191 iconBest = icon;
192 }
f618020a
MB
193 }
194
52734360
VZ
195#ifdef __WXMAC__
196 return wxIcon(iconBest.GetHICON(), size);
197#else
198 return iconBest;
199#endif
f618020a
MB
200}
201
52734360 202void wxIconBundle::AddIcon(const wxIcon& icon)
f618020a 203{
52734360 204 wxCHECK_RET( icon.IsOk(), _T("invalid icon") );
f618020a 205
52734360
VZ
206 AllocExclusive();
207
208 wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons;
209
210 // replace existing icon with the same size if we already have it
211 const size_t count = iconArray.size();
212 for ( size_t i = 0; i < count; ++i )
f618020a 213 {
52734360
VZ
214 wxIcon& tmp = iconArray[i];
215 if ( tmp.Ok() &&
216 tmp.GetWidth() == icon.GetWidth() &&
217 tmp.GetHeight() == icon.GetHeight() )
f618020a
MB
218 {
219 tmp = icon;
220 return;
221 }
222 }
223
52734360
VZ
224 // if we don't, add an icon with new size
225 iconArray.Add(icon);
f618020a 226}
52734360
VZ
227
228size_t wxIconBundle::GetIconCount() const
229{
230 return M_ICONBUNDLEDATA->m_icons.size();
231}
232
233wxIcon wxIconBundle::GetIconByIndex(size_t n) const
234{
235 return M_ICONBUNDLEDATA->m_icons[n];
236}
237