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