]> git.saurik.com Git - wxWidgets.git/blame - src/common/iconbndl.cpp
Rework the wxCusor ctor taking wx stock number to provide as many cursors as
[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
b5dbe15d 57 friend class wxIconBundle;
52734360
VZ
58};
59
60// ============================================================================
61// wxIconBundle implementation
62// ============================================================================
63
64wxIconBundle::wxIconBundle()
65 : wxGDIObject()
66{
52734360
VZ
67}
68
69wxIconBundle::wxIconBundle(const wxString& file, long type)
70 : wxGDIObject()
f618020a 71{
52734360
VZ
72 AddIcon(file, type);
73}
f618020a 74
52734360
VZ
75wxIconBundle::wxIconBundle(const wxIconBundle& icon)
76 : wxGDIObject()
77{
78 Ref(icon);
79}
f618020a 80
52734360
VZ
81wxIconBundle::wxIconBundle(const wxIcon& icon)
82 : wxGDIObject()
83{
52734360
VZ
84 AddIcon(icon);
85}
f618020a 86
52734360
VZ
87wxObjectRefData *wxIconBundle::CreateRefData() const
88{
89 return new wxIconBundleRefData;
90}
91
92wxObjectRefData *wxIconBundle::CloneRefData(const wxObjectRefData *data) const
93{
94 return new wxIconBundleRefData(*wx_static_cast(const wxIconBundleRefData *, data));
f618020a
MB
95}
96
97void wxIconBundle::DeleteIcons()
98{
52734360 99 UnRef();
f618020a
MB
100}
101
52734360
VZ
102bool wxIconBundle::IsOk() const
103{
104 return M_ICONBUNDLEDATA && !M_ICONBUNDLEDATA->m_icons.IsEmpty();
105}
106
107void wxIconBundle::AddIcon(const wxString& file, long type)
f618020a 108{
52734360
VZ
109#ifdef __WXMAC__
110 // Deal with standard icons
111 if ( type == wxBITMAP_TYPE_ICON_RESOURCE )
112 {
113 wxIcon tmp(file, type);
114 if (tmp.Ok())
115 {
116 AddIcon(tmp);
117 return;
118 }
119 }
120#endif // __WXMAC__
121
64c288fa 122#if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
f618020a 123 wxImage image;
f618020a 124
52734360
VZ
125 const size_t count = wxImage::GetImageCount( file, type );
126 for ( size_t i = 0; i < count; ++i )
f618020a 127 {
52734360 128 if ( !image.LoadFile( file, type, i ) )
f618020a
MB
129 {
130 wxLogError( _("Failed to load image %d from file '%s'."),
131 i, file.c_str() );
132 continue;
133 }
134
52734360
VZ
135 wxIcon tmp;
136 tmp.CopyFromBitmap(wxBitmap(image));
137 AddIcon(tmp);
f618020a 138 }
52734360
VZ
139#else // !wxUSE_IMAGE
140 wxUnusedVar(file);
141 wxUnusedVar(type);
142#endif // wxUSE_IMAGE/!wxUSE_IMAGE
f618020a
MB
143}
144
52734360 145wxIcon wxIconBundle::GetIcon(const wxSize& size) const
f618020a 146{
9fc3681a 147 const size_t count = GetIconCount();
8f696653 148
52734360
VZ
149 // optimize for the common case of icon bundles containing one icon only
150 wxIcon iconBest;
151 switch ( count )
f618020a 152 {
52734360
VZ
153 case 0:
154 // nothing to do, iconBest is already invalid
155 break;
156
157 case 1:
9fc3681a 158 iconBest = M_ICONBUNDLEDATA->m_icons[0];
52734360
VZ
159 break;
160
161 default:
162 // there is more than one icon, find the best match:
163 wxCoord sysX = wxSystemSettings::GetMetric( wxSYS_ICON_X ),
164 sysY = wxSystemSettings::GetMetric( wxSYS_ICON_Y );
165
9fc3681a 166 const wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons;
52734360
VZ
167 for ( size_t i = 0; i < count; i++ )
168 {
169 const wxIcon& icon = iconArray[i];
170 wxCoord sx = icon.GetWidth(),
171 sy = icon.GetHeight();
172
173 // if we got an icon of exactly the requested size, we're done
174 if ( sx == size.x && sy == size.y )
175 {
176 iconBest = icon;
177 break;
178 }
179
180 // the best icon is by default (arbitrarily) the first one but
181 // if we find a system-sized icon, take it instead
182 if ( sx == sysX && sy == sysY || !iconBest.IsOk() )
183 iconBest = icon;
184 }
f618020a
MB
185 }
186
52734360
VZ
187#ifdef __WXMAC__
188 return wxIcon(iconBest.GetHICON(), size);
189#else
190 return iconBest;
191#endif
f618020a
MB
192}
193
9b5933bc
VZ
194wxIcon wxIconBundle::GetIconOfExactSize(const wxSize& size) const
195{
196 wxIcon icon = GetIcon(size);
197 if ( icon.Ok() &&
198 (icon.GetWidth() != size.x || icon.GetHeight() != size.y) )
199 {
200 icon = wxNullIcon;
201 }
202
203 return icon;
204}
205
52734360 206void wxIconBundle::AddIcon(const wxIcon& icon)
f618020a 207{
52734360 208 wxCHECK_RET( icon.IsOk(), _T("invalid icon") );
f618020a 209
52734360
VZ
210 AllocExclusive();
211
212 wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons;
213
214 // replace existing icon with the same size if we already have it
215 const size_t count = iconArray.size();
216 for ( size_t i = 0; i < count; ++i )
f618020a 217 {
52734360
VZ
218 wxIcon& tmp = iconArray[i];
219 if ( tmp.Ok() &&
220 tmp.GetWidth() == icon.GetWidth() &&
221 tmp.GetHeight() == icon.GetHeight() )
f618020a
MB
222 {
223 tmp = icon;
224 return;
225 }
226 }
227
52734360
VZ
228 // if we don't, add an icon with new size
229 iconArray.Add(icon);
f618020a 230}
52734360
VZ
231
232size_t wxIconBundle::GetIconCount() const
233{
9fc3681a 234 return IsOk() ? M_ICONBUNDLEDATA->m_icons.size() : 0;
52734360
VZ
235}
236
237wxIcon wxIconBundle::GetIconByIndex(size_t n) const
238{
9fc3681a
VZ
239 wxCHECK_MSG( n < GetIconCount(), wxNullIcon, _T("invalid index") );
240
52734360
VZ
241 return M_ICONBUNDLEDATA->m_icons[n];
242}
243