]>
Commit | Line | Data |
---|---|---|
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 | |
23 | IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject) | |
24 | ||
25 | #define M_ICONDATA ((wxIconRefData *)m_refData) | |
26 | ||
27 | class WXDLLEXPORT wxIconRefData : public wxGDIRefData | |
28 | { | |
29 | public: | |
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 | ||
46 | private: | |
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 | ||
58 | wxIconRefData::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 | ||
67 | void wxIconRefData::Init() | |
68 | { | |
69 | m_iconRef = NULL ; | |
70 | m_width = | |
71 | m_height = 0; | |
72 | } | |
73 | ||
74 | void wxIconRefData::Free() | |
75 | { | |
76 | if ( m_iconRef ) | |
77 | { | |
78 | ReleaseIconRef( m_iconRef ) ; | |
79 | m_iconRef = NULL ; | |
80 | } | |
81 | } | |
82 | ||
83 | // | |
84 | // | |
85 | // | |
86 | ||
87 | wxIcon::wxIcon() | |
88 | { | |
89 | } | |
90 | ||
91 | wxIcon::wxIcon( const char bits[], int width, int height ) | |
92 | { | |
93 | wxBitmap bmp( bits, width, height ) ; | |
94 | CopyFromBitmap( bmp ) ; | |
95 | } | |
96 | ||
97 | wxIcon::wxIcon(const char* const* bits) | |
98 | { | |
99 | wxBitmap bmp( bits ) ; | |
100 | CopyFromBitmap( bmp ) ; | |
101 | } | |
102 | ||
103 | wxIcon::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 | ||
110 | wxIcon::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 | ||
120 | wxIcon::~wxIcon() | |
121 | { | |
122 | } | |
123 | ||
124 | wxGDIRefData *wxIcon::CreateGDIRefData() const | |
125 | { | |
126 | return new wxIconRefData; | |
127 | } | |
128 | ||
f9b4d680 VZ |
129 | wxGDIRefData * |
130 | wxIcon::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 | ||
137 | WXHICON wxIcon::GetHICON() const | |
138 | { | |
a1b806b9 | 139 | wxASSERT( IsOk() ) ; |
489468fe SC |
140 | |
141 | return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ; | |
142 | } | |
143 | ||
144 | int wxIcon::GetWidth() const | |
145 | { | |
a1b806b9 | 146 | wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") ); |
489468fe SC |
147 | |
148 | return M_ICONDATA->GetWidth(); | |
149 | } | |
150 | ||
151 | int wxIcon::GetHeight() const | |
152 | { | |
a1b806b9 | 153 | wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") ); |
489468fe SC |
154 | |
155 | return M_ICONDATA->GetHeight(); | |
156 | } | |
157 | ||
158 | int wxIcon::GetDepth() const | |
159 | { | |
160 | return 32; | |
161 | } | |
162 | ||
163 | void wxIcon::SetDepth( int WXUNUSED(depth) ) | |
164 | { | |
165 | } | |
166 | ||
167 | void wxIcon::SetWidth( int WXUNUSED(width) ) | |
168 | { | |
169 | } | |
170 | ||
171 | void 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 |
177 | bool 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 | |
200 | bool 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 | |
297 | bool 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 | |
356 | bool 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 | |
396 | bool 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 |
437 | void 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 | ||
459 | IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler) | |
460 | ||
461 | bool 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 |