1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/icon.cpp
3 // Purpose: wxIcon class
4 // Author: Stefan Csomor
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
13 #if wxOSX_USE_COCOA_OR_CARBON
21 #include "wx/osx/private.h"
23 IMPLEMENT_DYNAMIC_CLASS(wxIcon
, wxGDIObject
)
25 #define M_ICONDATA ((wxIconRefData *)m_refData)
27 class WXDLLEXPORT wxIconRefData
: public wxGDIRefData
30 wxIconRefData() { Init(); }
31 wxIconRefData( WXHICON iconref
, int desiredWidth
, int desiredHeight
);
32 virtual ~wxIconRefData() { Free(); }
34 virtual bool IsOk() const { return m_iconRef
!= NULL
; }
38 void SetWidth( int width
) { m_width
= width
; }
39 void SetHeight( int height
) { m_height
= height
; }
41 int GetWidth() const { return m_width
; }
42 int GetHeight() const { return m_height
; }
44 WXHICON
GetHICON() const { return (WXHICON
) m_iconRef
; }
53 // We can (easily) copy m_iconRef so we don't implement the copy ctor.
54 wxDECLARE_NO_COPY_CLASS(wxIconRefData
);
58 wxIconRefData::wxIconRefData( WXHICON icon
, int desiredWidth
, int desiredHeight
)
60 m_iconRef
= (IconRef
)( icon
) ;
63 SetWidth( desiredWidth
== -1 ? 32 : desiredWidth
) ;
64 SetHeight( desiredHeight
== -1 ? 32 : desiredHeight
) ;
67 void wxIconRefData::Init()
74 void wxIconRefData::Free()
78 ReleaseIconRef( m_iconRef
) ;
91 wxIcon::wxIcon( const char bits
[], int width
, int height
)
93 wxBitmap
bmp( bits
, width
, height
) ;
94 CopyFromBitmap( bmp
) ;
97 wxIcon::wxIcon(const char* const* bits
)
99 wxBitmap
bmp( bits
) ;
100 CopyFromBitmap( bmp
) ;
104 const wxString
& icon_file
, wxBitmapType flags
,
105 int desiredWidth
, int desiredHeight
)
107 LoadFile( icon_file
, flags
, desiredWidth
, desiredHeight
);
110 wxIcon::wxIcon(WXHICON icon
, const wxSize
& size
)
113 // as the icon owns that ref, we have to acquire it as well
115 AcquireIconRef( (IconRef
) icon
) ;
117 m_refData
= new wxIconRefData( icon
, size
.x
, size
.y
) ;
124 wxGDIRefData
*wxIcon::CreateGDIRefData() const
126 return new wxIconRefData
;
130 wxIcon::CloneGDIRefData(const wxGDIRefData
* WXUNUSED(data
)) const
132 wxFAIL_MSG( wxS("Cloning icons is not implemented in wxCarbon.") );
134 return new wxIconRefData
;
137 WXHICON
wxIcon::GetHICON() const
141 return (WXHICON
) ((wxIconRefData
*)m_refData
)->GetHICON() ;
144 int wxIcon::GetWidth() const
146 wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
148 return M_ICONDATA
->GetWidth();
151 int wxIcon::GetHeight() const
153 wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
155 return M_ICONDATA
->GetHeight();
158 int wxIcon::GetDepth() const
163 void wxIcon::SetDepth( int WXUNUSED(depth
) )
167 void wxIcon::SetWidth( int WXUNUSED(width
) )
171 void wxIcon::SetHeight( int WXUNUSED(height
) )
175 // Load an icon based on resource name or filel name
176 // Return true on success, false otherwise
177 bool wxIcon::LoadFile(
178 const wxString
& filename
, wxBitmapType type
,
179 int desiredWidth
, int desiredHeight
)
181 if( type
== wxBITMAP_TYPE_ICON_RESOURCE
)
183 if( LoadIconFromSystemResource( filename
, desiredWidth
, desiredHeight
) )
186 return LoadIconFromBundleResource( filename
, desiredWidth
, desiredHeight
);
188 else if( type
== wxBITMAP_TYPE_ICON
)
190 return LoadIconFromFile( filename
, desiredWidth
, desiredHeight
);
194 return LoadIconAsBitmap( filename
, type
, desiredWidth
, desiredHeight
);
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
)
206 if ( resourceName
== wxT("wxICON_INFORMATION") )
208 theId
= kAlertNoteIcon
;
210 else if ( resourceName
== wxT("wxICON_QUESTION") )
212 theId
= kAlertCautionIcon
;
214 else if ( resourceName
== wxT("wxICON_WARNING") )
216 theId
= kAlertCautionIcon
;
218 else if ( resourceName
== wxT("wxICON_ERROR") )
220 theId
= kAlertStopIcon
;
222 else if ( resourceName
== wxT("wxICON_FOLDER") )
224 theId
= kGenericFolderIcon
;
226 else if ( resourceName
== wxT("wxICON_FOLDER_OPEN") )
228 theId
= kOpenFolderIcon
;
230 else if ( resourceName
== wxT("wxICON_NORMAL_FILE") )
232 theId
= kGenericDocumentIcon
;
234 else if ( resourceName
== wxT("wxICON_EXECUTABLE_FILE") )
236 theId
= kGenericApplicationIcon
;
238 else if ( resourceName
== wxT("wxICON_CDROM") )
240 theId
= kGenericCDROMIcon
;
242 else if ( resourceName
== wxT("wxICON_FLOPPY") )
244 theId
= kGenericFloppyIcon
;
246 else if ( resourceName
== wxT("wxICON_HARDDISK") )
248 theId
= kGenericHardDiskIcon
;
250 else if ( resourceName
== wxT("wxICON_REMOVABLE") )
252 theId
= kGenericRemovableMediaIcon
;
254 else if ( resourceName
== wxT("wxICON_DELETE") )
256 theId
= kToolbarDeleteIcon
;
258 else if ( resourceName
== wxT("wxICON_GO_BACK") )
260 theId
= kBackwardArrowIcon
;
262 else if ( resourceName
== wxT("wxICON_GO_FORWARD") )
264 theId
= kForwardArrowIcon
;
266 else if ( resourceName
== wxT("wxICON_GO_HOME") )
268 theId
= kToolbarHomeIcon
;
270 else if ( resourceName
== wxT("wxICON_HELP_SETTINGS") )
272 theId
= kGenericFontIcon
;
274 else if ( resourceName
== wxT("wxICON_HELP_PAGE") )
276 theId
= kGenericDocumentIcon
;
281 IconRef iconRef
= NULL
;
282 verify_noerr( GetIconRef( kOnSystemDisk
, kSystemIconsCreator
, theId
, &iconRef
) ) ;
285 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
) ;
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
)
301 IconRef iconRef
= NULL
;
303 // first look in the resource fork
304 if ( iconRef
== NULL
)
308 wxMacStringToPascal( resourceName
, theName
) ;
309 Handle resHandle
= GetNamedResource( 'icns' , theName
) ;
310 if ( resHandle
!= 0L )
312 IconFamilyHandle iconFamily
= (IconFamilyHandle
) resHandle
;
313 OSStatus err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
317 wxFAIL_MSG("Error when constructing icon ref");
320 ReleaseResource( resHandle
) ;
323 if ( iconRef
== NULL
)
325 wxCFStringRef
name(resourceName
);
328 wxCFRef
<CFURLRef
> iconURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), name
, CFSTR("icns"), NULL
));
330 if (CFURLGetFSRef(iconURL
, &iconFSRef
))
332 // Get a handle on the icon family
333 IconFamilyHandle iconFamily
;
334 OSStatus err
= ReadIconFromFSRef( &iconFSRef
, &iconFamily
);
338 err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
340 ReleaseResource( (Handle
) iconFamily
);
346 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
);
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
)
363 // Get a file system reference
365 err
= FSPathMakeRef( (const wxUint8
*)filename
.utf8_str().data(), &fsRef
, NULL
);
370 // Get a handle on the icon family
371 IconFamilyHandle iconFamily
;
372 err
= ReadIconFromFSRef( &fsRef
, &iconFamily
);
377 // Get the icon reference itself
379 err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
383 // If everything is OK, assign m_refData
384 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
);
388 // Release the iconFamily before returning
389 ReleaseResource( (Handle
) iconFamily
);
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
)
400 wxBitmapHandler
*handler
= wxBitmap::FindHandler( type
);
405 if ( handler
->LoadFile( &bmp
, filename
, type
, desiredWidth
, desiredHeight
))
407 CopyFromBitmap( bmp
) ;
415 wxImage
loadimage( filename
, type
);
416 if (loadimage
.IsOk())
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
) ;
425 wxBitmap
bmp( loadimage
);
426 CopyFromBitmap( bmp
) ;
437 void wxIcon::CopyFromBitmap( const wxBitmap
& bmp
)
441 // as the bitmap owns that ref, we have to acquire it as well
443 int w
= bmp
.GetWidth() ;
444 int h
= bmp
.GetHeight() ;
445 int sz
= wxMax( w
, h
) ;
447 if ( sz
== 24 || sz
== 64 )
449 wxBitmap
scaleBmp( bmp
.ConvertToImage().Scale( w
* 2 , h
* 2 ) ) ;
450 m_refData
= new wxIconRefData( (WXHICON
) scaleBmp
.CreateIconRef(), bmp
.GetWidth(), bmp
.GetHeight() ) ;
454 m_refData
= new wxIconRefData( (WXHICON
) bmp
.CreateIconRef() , bmp
.GetWidth(), bmp
.GetHeight() ) ;
459 IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler
, wxBitmapHandler
)
461 bool wxICONResourceHandler::LoadFile(
462 wxBitmap
*bitmap
, const wxString
& name
, wxBitmapType
WXUNUSED(flags
),
463 int desiredWidth
, int desiredHeight
)
466 if ( icon
.LoadFile( name
, wxBITMAP_TYPE_ICON_RESOURCE
, desiredWidth
, desiredHeight
) )
468 bitmap
->CopyFromIcon( icon
) ;
469 return bitmap
->IsOk() ;