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