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