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