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