]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/icon.cpp
adding mimetype patch, closes #12072
[wxWidgets.git] / src / osx / carbon / icon.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/icon.cpp
3 // Purpose: wxIcon class
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxOSX_USE_COCOA_OR_CARBON
15
16 #include "wx/icon.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/image.h"
20 #endif
21
22 #include "wx/osx/private.h"
23
24 IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject)
25
26 #define M_ICONDATA ((wxIconRefData *)m_refData)
27
28 class WXDLLEXPORT wxIconRefData : public wxGDIRefData
29 {
30 public:
31 wxIconRefData() { Init(); }
32 wxIconRefData( WXHICON iconref, int desiredWidth, int desiredHeight );
33 virtual ~wxIconRefData() { Free(); }
34
35 virtual bool IsOk() const { return m_iconRef != NULL; }
36
37 virtual void Free();
38
39 void SetWidth( int width ) { m_width = width; }
40 void SetHeight( int height ) { m_height = height; }
41
42 int GetWidth() const { return m_width; }
43 int GetHeight() const { return m_height; }
44
45 WXHICON GetHICON() const { return (WXHICON) m_iconRef; }
46
47 private:
48 void Init();
49
50 IconRef m_iconRef;
51 int m_width;
52 int m_height;
53 };
54
55
56 wxIconRefData::wxIconRefData( WXHICON icon, int desiredWidth, int desiredHeight )
57 {
58 m_iconRef = (IconRef)( icon ) ;
59
60 // Standard sizes
61 SetWidth( desiredWidth == -1 ? 32 : desiredWidth ) ;
62 SetHeight( desiredHeight == -1 ? 32 : desiredHeight ) ;
63 }
64
65 void wxIconRefData::Init()
66 {
67 m_iconRef = NULL ;
68 m_width =
69 m_height = 0;
70 }
71
72 void wxIconRefData::Free()
73 {
74 if ( m_iconRef )
75 {
76 ReleaseIconRef( m_iconRef ) ;
77 m_iconRef = NULL ;
78 }
79 }
80
81 //
82 //
83 //
84
85 wxIcon::wxIcon()
86 {
87 }
88
89 wxIcon::wxIcon( const char bits[], int width, int height )
90 {
91 wxBitmap bmp( bits, width, height ) ;
92 CopyFromBitmap( bmp ) ;
93 }
94
95 wxIcon::wxIcon(const char* const* bits)
96 {
97 wxBitmap bmp( bits ) ;
98 CopyFromBitmap( bmp ) ;
99 }
100
101 wxIcon::wxIcon(
102 const wxString& icon_file, wxBitmapType flags,
103 int desiredWidth, int desiredHeight )
104 {
105 LoadFile( icon_file, flags, desiredWidth, desiredHeight );
106 }
107
108 wxIcon::wxIcon(WXHICON icon, const wxSize& size)
109 : wxGDIObject()
110 {
111 // as the icon owns that ref, we have to acquire it as well
112 if (icon)
113 AcquireIconRef( (IconRef) icon ) ;
114
115 m_refData = new wxIconRefData( icon, size.x, size.y ) ;
116 }
117
118 wxIcon::~wxIcon()
119 {
120 }
121
122 wxGDIRefData *wxIcon::CreateGDIRefData() const
123 {
124 return new wxIconRefData;
125 }
126
127 wxGDIRefData *wxIcon::CloneGDIRefData(const wxGDIRefData *data) const
128 {
129 return new wxIconRefData(*static_cast<const wxIconRefData *>(data));
130 }
131
132 WXHICON wxIcon::GetHICON() const
133 {
134 wxASSERT( Ok() ) ;
135
136 return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ;
137 }
138
139 int wxIcon::GetWidth() const
140 {
141 wxCHECK_MSG( Ok(), -1, wxT("invalid icon") );
142
143 return M_ICONDATA->GetWidth();
144 }
145
146 int wxIcon::GetHeight() const
147 {
148 wxCHECK_MSG( Ok(), -1, wxT("invalid icon") );
149
150 return M_ICONDATA->GetHeight();
151 }
152
153 int wxIcon::GetDepth() const
154 {
155 return 32;
156 }
157
158 void wxIcon::SetDepth( int WXUNUSED(depth) )
159 {
160 }
161
162 void wxIcon::SetWidth( int WXUNUSED(width) )
163 {
164 }
165
166 void wxIcon::SetHeight( int WXUNUSED(height) )
167 {
168 }
169
170 // Load an icon based on resource name or filel name
171 // Return true on success, false otherwise
172 bool wxIcon::LoadFile(
173 const wxString& filename, wxBitmapType type,
174 int desiredWidth, int desiredHeight )
175 {
176 if( type == wxBITMAP_TYPE_ICON_RESOURCE )
177 {
178 if( LoadIconFromSystemResource( filename, desiredWidth, desiredHeight ) )
179 return true;
180 else
181 return LoadIconFromBundleResource( filename, desiredWidth, desiredHeight );
182 }
183 else if( type == wxBITMAP_TYPE_ICON )
184 {
185 return LoadIconFromFile( filename, desiredWidth, desiredHeight );
186 }
187 else
188 {
189 return LoadIconAsBitmap( filename, type, desiredWidth, desiredHeight );
190 }
191 }
192
193 // Load a well known system icon by its wxWidgets identifier
194 // Returns true on success, false otherwise
195 bool wxIcon::LoadIconFromSystemResource(const wxString& resourceName, int desiredWidth, int desiredHeight)
196 {
197 UnRef();
198
199 OSType theId = 0 ;
200
201 if ( resourceName == wxT("wxICON_INFORMATION") )
202 {
203 theId = kAlertNoteIcon ;
204 }
205 else if ( resourceName == wxT("wxICON_QUESTION") )
206 {
207 theId = kAlertCautionIcon ;
208 }
209 else if ( resourceName == wxT("wxICON_WARNING") )
210 {
211 theId = kAlertCautionIcon ;
212 }
213 else if ( resourceName == wxT("wxICON_ERROR") )
214 {
215 theId = kAlertStopIcon ;
216 }
217 else if ( resourceName == wxT("wxICON_FOLDER") )
218 {
219 theId = kGenericFolderIcon ;
220 }
221 else if ( resourceName == wxT("wxICON_FOLDER_OPEN") )
222 {
223 theId = kOpenFolderIcon ;
224 }
225 else if ( resourceName == wxT("wxICON_NORMAL_FILE") )
226 {
227 theId = kGenericDocumentIcon ;
228 }
229 else if ( resourceName == wxT("wxICON_EXECUTABLE_FILE") )
230 {
231 theId = kGenericApplicationIcon ;
232 }
233 else if ( resourceName == wxT("wxICON_CDROM") )
234 {
235 theId = kGenericCDROMIcon ;
236 }
237 else if ( resourceName == wxT("wxICON_FLOPPY") )
238 {
239 theId = kGenericFloppyIcon ;
240 }
241 else if ( resourceName == wxT("wxICON_HARDDISK") )
242 {
243 theId = kGenericHardDiskIcon ;
244 }
245 else if ( resourceName == wxT("wxICON_REMOVABLE") )
246 {
247 theId = kGenericRemovableMediaIcon ;
248 }
249 else if ( resourceName == wxT("wxICON_DELETE") )
250 {
251 theId = kToolbarDeleteIcon ;
252 }
253 else if ( resourceName == wxT("wxICON_GO_BACK") )
254 {
255 theId = kBackwardArrowIcon ;
256 }
257 else if ( resourceName == wxT("wxICON_GO_FORWARD") )
258 {
259 theId = kForwardArrowIcon ;
260 }
261 else if ( resourceName == wxT("wxICON_GO_HOME") )
262 {
263 theId = kToolbarHomeIcon ;
264 }
265 else if ( resourceName == wxT("wxICON_HELP_SETTINGS") )
266 {
267 theId = kGenericFontIcon ;
268 }
269 else if ( resourceName == wxT("wxICON_HELP_PAGE") )
270 {
271 theId = kGenericDocumentIcon ;
272 }
273
274 if ( theId != 0 )
275 {
276 IconRef iconRef = NULL ;
277 verify_noerr( GetIconRef( kOnSystemDisk, kSystemIconsCreator, theId, &iconRef ) ) ;
278 if ( iconRef )
279 {
280 m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ) ;
281 return true ;
282 }
283 }
284
285 return false;
286 }
287
288 // Load an icon of type 'icns' by resource by name
289 // The resource must exist in one of the currently accessible bundles
290 // (usually this means the application bundle for the current application)
291 // Return true on success, false otherwise
292 bool wxIcon::LoadIconFromBundleResource(const wxString& resourceName, int desiredWidth, int desiredHeight)
293 {
294 UnRef();
295
296 IconRef iconRef = NULL ;
297
298 // first look in the resource fork
299 if ( iconRef == NULL )
300 {
301 Str255 theName ;
302
303 wxMacStringToPascal( resourceName , theName ) ;
304 Handle resHandle = GetNamedResource( 'icns' , theName ) ;
305 if ( resHandle != 0L )
306 {
307 IconFamilyHandle iconFamily = (IconFamilyHandle) resHandle ;
308 OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef );
309
310 if ( err != noErr )
311 {
312 wxFAIL_MSG("Error when constructing icon ref");
313 }
314
315 ReleaseResource( resHandle ) ;
316 }
317 }
318
319 if ( iconRef )
320 {
321 m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight );
322 return true;
323 }
324
325 return false;
326 }
327
328 // Load an icon from an icon file using the underlying OS X API
329 // The icon file must be in a format understood by the OS
330 // Return true for success, false otherwise
331 bool wxIcon::LoadIconFromFile(const wxString& filename, int desiredWidth, int desiredHeight)
332 {
333 UnRef();
334
335 OSStatus err;
336 bool result = false;
337
338 // Get a file system reference
339 FSRef fsRef;
340 err = FSPathMakeRef( (const wxUint8*)filename.utf8_str().data(), &fsRef, NULL );
341
342 if( err != noErr )
343 return false;
344
345 // Get a handle on the icon family
346 IconFamilyHandle iconFamily;
347 err = ReadIconFromFSRef( &fsRef, &iconFamily );
348
349 if( err != noErr )
350 return false;
351
352 // Get the icon reference itself
353 IconRef iconRef;
354 err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef );
355
356 if( err == noErr )
357 {
358 // If everthing is OK, assign m_refData
359 m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight );
360 result = true;
361 }
362
363 // Release the iconFamily before returning
364 ReleaseResource( (Handle) iconFamily );
365 return result;
366 }
367
368 // Load an icon from a file using functionality from wxWidgets
369 // A suitable bitmap handler (or image handler) must be available
370 // Return true on success, false otherwise
371 bool wxIcon::LoadIconAsBitmap(const wxString& filename, wxBitmapType type, int desiredWidth, int desiredHeight)
372 {
373 UnRef();
374
375 wxBitmapHandler *handler = wxBitmap::FindHandler( type );
376
377 if ( handler )
378 {
379 wxBitmap bmp ;
380 if ( handler->LoadFile( &bmp , filename, type, desiredWidth, desiredHeight ))
381 {
382 CopyFromBitmap( bmp ) ;
383 return true ;
384 }
385 }
386
387 #if wxUSE_IMAGE
388 else
389 {
390 wxImage loadimage( filename, type );
391 if (loadimage.Ok())
392 {
393 if ( desiredWidth == -1 )
394 desiredWidth = loadimage.GetWidth() ;
395 if ( desiredHeight == -1 )
396 desiredHeight = loadimage.GetHeight() ;
397 if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() )
398 loadimage.Rescale( desiredWidth , desiredHeight ) ;
399
400 wxBitmap bmp( loadimage );
401 CopyFromBitmap( bmp ) ;
402
403 return true;
404 }
405 }
406 #endif
407
408 return false;
409 }
410
411
412 void wxIcon::CopyFromBitmap( const wxBitmap& bmp )
413 {
414 UnRef() ;
415
416 // as the bitmap owns that ref, we have to acquire it as well
417 IconRef iconRef = bmp.CreateIconRef() ;
418 m_refData = new wxIconRefData( (WXHICON) iconRef, bmp.GetWidth(), bmp.GetHeight() ) ;
419 }
420
421 IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler)
422
423 bool wxICONResourceHandler::LoadFile(
424 wxBitmap *bitmap, const wxString& name, wxBitmapType WXUNUSED(flags),
425 int desiredWidth, int desiredHeight )
426 {
427 wxIcon icon ;
428 if ( icon.LoadFile( name , wxBITMAP_TYPE_ICON_RESOURCE , desiredWidth , desiredHeight ) )
429 {
430 bitmap->CopyFromIcon( icon ) ;
431 return bitmap->Ok() ;
432 }
433 return false;
434 }
435
436 #endif
437