1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/icon.cpp
3 // Purpose: wxIcon class
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #if wxOSX_USE_COCOA_OR_CARBON
22 #include "wx/osx/private.h"
24 IMPLEMENT_DYNAMIC_CLASS(wxIcon
, wxGDIObject
)
26 #define M_ICONDATA ((wxIconRefData *)m_refData)
28 class WXDLLEXPORT wxIconRefData
: public wxGDIRefData
31 wxIconRefData() { Init(); }
32 wxIconRefData( WXHICON iconref
, int desiredWidth
, int desiredHeight
);
33 virtual ~wxIconRefData() { Free(); }
35 virtual bool IsOk() const { return m_iconRef
!= NULL
; }
39 void SetWidth( int width
) { m_width
= width
; }
40 void SetHeight( int height
) { m_height
= height
; }
42 int GetWidth() const { return m_width
; }
43 int GetHeight() const { return m_height
; }
45 WXHICON
GetHICON() const { return (WXHICON
) m_iconRef
; }
54 // We can (easily) copy m_iconRef so we don't implement the copy ctor.
55 wxDECLARE_NO_COPY_CLASS(wxIconRefData
);
59 wxIconRefData::wxIconRefData( WXHICON icon
, int desiredWidth
, int desiredHeight
)
61 m_iconRef
= (IconRef
)( icon
) ;
64 SetWidth( desiredWidth
== -1 ? 32 : desiredWidth
) ;
65 SetHeight( desiredHeight
== -1 ? 32 : desiredHeight
) ;
68 void wxIconRefData::Init()
75 void wxIconRefData::Free()
79 ReleaseIconRef( m_iconRef
) ;
92 wxIcon::wxIcon( const char bits
[], int width
, int height
)
94 wxBitmap
bmp( bits
, width
, height
) ;
95 CopyFromBitmap( bmp
) ;
98 wxIcon::wxIcon(const char* const* bits
)
100 wxBitmap
bmp( bits
) ;
101 CopyFromBitmap( bmp
) ;
105 const wxString
& icon_file
, wxBitmapType flags
,
106 int desiredWidth
, int desiredHeight
)
108 LoadFile( icon_file
, flags
, desiredWidth
, desiredHeight
);
111 wxIcon::wxIcon(WXHICON icon
, const wxSize
& size
)
114 // as the icon owns that ref, we have to acquire it as well
116 AcquireIconRef( (IconRef
) icon
) ;
118 m_refData
= new wxIconRefData( icon
, size
.x
, size
.y
) ;
125 wxGDIRefData
*wxIcon::CreateGDIRefData() const
127 return new wxIconRefData
;
131 wxIcon::CloneGDIRefData(const wxGDIRefData
* WXUNUSED(data
)) const
133 wxFAIL_MSG( wxS("Cloning icons is not implemented in wxCarbon.") );
135 return new wxIconRefData
;
138 WXHICON
wxIcon::GetHICON() const
142 return (WXHICON
) ((wxIconRefData
*)m_refData
)->GetHICON() ;
145 int wxIcon::GetWidth() const
147 wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
149 return M_ICONDATA
->GetWidth();
152 int wxIcon::GetHeight() const
154 wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
156 return M_ICONDATA
->GetHeight();
159 int wxIcon::GetDepth() const
164 void wxIcon::SetDepth( int WXUNUSED(depth
) )
168 void wxIcon::SetWidth( int WXUNUSED(width
) )
172 void wxIcon::SetHeight( int WXUNUSED(height
) )
176 // Load an icon based on resource name or filel name
177 // Return true on success, false otherwise
178 bool wxIcon::LoadFile(
179 const wxString
& filename
, wxBitmapType type
,
180 int desiredWidth
, int desiredHeight
)
182 if( type
== wxBITMAP_TYPE_ICON_RESOURCE
)
184 if( LoadIconFromSystemResource( filename
, desiredWidth
, desiredHeight
) )
187 return LoadIconFromBundleResource( filename
, desiredWidth
, desiredHeight
);
189 else if( type
== wxBITMAP_TYPE_ICON
)
191 return LoadIconFromFile( filename
, desiredWidth
, desiredHeight
);
195 return LoadIconAsBitmap( filename
, type
, desiredWidth
, desiredHeight
);
199 // Load a well known system icon by its wxWidgets identifier
200 // Returns true on success, false otherwise
201 bool wxIcon::LoadIconFromSystemResource(const wxString
& resourceName
, int desiredWidth
, int desiredHeight
)
207 if ( resourceName
== wxT("wxICON_INFORMATION") )
209 theId
= kAlertNoteIcon
;
211 else if ( resourceName
== wxT("wxICON_QUESTION") )
213 theId
= kAlertCautionIcon
;
215 else if ( resourceName
== wxT("wxICON_WARNING") )
217 theId
= kAlertCautionIcon
;
219 else if ( resourceName
== wxT("wxICON_ERROR") )
221 theId
= kAlertStopIcon
;
223 else if ( resourceName
== wxT("wxICON_FOLDER") )
225 theId
= kGenericFolderIcon
;
227 else if ( resourceName
== wxT("wxICON_FOLDER_OPEN") )
229 theId
= kOpenFolderIcon
;
231 else if ( resourceName
== wxT("wxICON_NORMAL_FILE") )
233 theId
= kGenericDocumentIcon
;
235 else if ( resourceName
== wxT("wxICON_EXECUTABLE_FILE") )
237 theId
= kGenericApplicationIcon
;
239 else if ( resourceName
== wxT("wxICON_CDROM") )
241 theId
= kGenericCDROMIcon
;
243 else if ( resourceName
== wxT("wxICON_FLOPPY") )
245 theId
= kGenericFloppyIcon
;
247 else if ( resourceName
== wxT("wxICON_HARDDISK") )
249 theId
= kGenericHardDiskIcon
;
251 else if ( resourceName
== wxT("wxICON_REMOVABLE") )
253 theId
= kGenericRemovableMediaIcon
;
255 else if ( resourceName
== wxT("wxICON_DELETE") )
257 theId
= kToolbarDeleteIcon
;
259 else if ( resourceName
== wxT("wxICON_GO_BACK") )
261 theId
= kBackwardArrowIcon
;
263 else if ( resourceName
== wxT("wxICON_GO_FORWARD") )
265 theId
= kForwardArrowIcon
;
267 else if ( resourceName
== wxT("wxICON_GO_HOME") )
269 theId
= kToolbarHomeIcon
;
271 else if ( resourceName
== wxT("wxICON_HELP_SETTINGS") )
273 theId
= kGenericFontIcon
;
275 else if ( resourceName
== wxT("wxICON_HELP_PAGE") )
277 theId
= kGenericDocumentIcon
;
282 IconRef iconRef
= NULL
;
283 verify_noerr( GetIconRef( kOnSystemDisk
, kSystemIconsCreator
, theId
, &iconRef
) ) ;
286 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
) ;
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
298 bool wxIcon::LoadIconFromBundleResource(const wxString
& resourceName
, int desiredWidth
, int desiredHeight
)
302 IconRef iconRef
= NULL
;
304 // first look in the resource fork
305 if ( iconRef
== NULL
)
309 wxMacStringToPascal( resourceName
, theName
) ;
310 Handle resHandle
= GetNamedResource( 'icns' , theName
) ;
311 if ( resHandle
!= 0L )
313 IconFamilyHandle iconFamily
= (IconFamilyHandle
) resHandle
;
314 OSStatus err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
318 wxFAIL_MSG("Error when constructing icon ref");
321 ReleaseResource( resHandle
) ;
324 if ( iconRef
== NULL
)
326 wxCFStringRef
name(resourceName
);
329 wxCFRef
<CFURLRef
> iconURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), name
, CFSTR("icns"), NULL
));
331 if (CFURLGetFSRef(iconURL
, &iconFSRef
))
333 // Get a handle on the icon family
334 IconFamilyHandle iconFamily
;
335 OSStatus err
= ReadIconFromFSRef( &iconFSRef
, &iconFamily
);
339 err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
341 ReleaseResource( (Handle
) iconFamily
);
347 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
);
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
357 bool wxIcon::LoadIconFromFile(const wxString
& filename
, int desiredWidth
, int desiredHeight
)
364 // Get a file system reference
366 err
= FSPathMakeRef( (const wxUint8
*)filename
.utf8_str().data(), &fsRef
, NULL
);
371 // Get a handle on the icon family
372 IconFamilyHandle iconFamily
;
373 err
= ReadIconFromFSRef( &fsRef
, &iconFamily
);
378 // Get the icon reference itself
380 err
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &iconRef
);
384 // If everything is OK, assign m_refData
385 m_refData
= new wxIconRefData( (WXHICON
) iconRef
, desiredWidth
, desiredHeight
);
389 // Release the iconFamily before returning
390 ReleaseResource( (Handle
) iconFamily
);
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
397 bool wxIcon::LoadIconAsBitmap(const wxString
& filename
, wxBitmapType type
, int desiredWidth
, int desiredHeight
)
401 wxBitmapHandler
*handler
= wxBitmap::FindHandler( type
);
406 if ( handler
->LoadFile( &bmp
, filename
, type
, desiredWidth
, desiredHeight
))
408 CopyFromBitmap( bmp
) ;
416 wxImage
loadimage( filename
, type
);
417 if (loadimage
.IsOk())
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
) ;
426 wxBitmap
bmp( loadimage
);
427 CopyFromBitmap( bmp
) ;
438 void wxIcon::CopyFromBitmap( const wxBitmap
& bmp
)
442 // as the bitmap owns that ref, we have to acquire it as well
444 int w
= bmp
.GetWidth() ;
445 int h
= bmp
.GetHeight() ;
446 int sz
= wxMax( w
, h
) ;
448 if ( sz
== 24 || sz
== 64 )
450 wxBitmap
scaleBmp( bmp
.ConvertToImage().Scale( w
* 2 , h
* 2 ) ) ;
451 m_refData
= new wxIconRefData( (WXHICON
) scaleBmp
.CreateIconRef(), bmp
.GetWidth(), bmp
.GetHeight() ) ;
455 m_refData
= new wxIconRefData( (WXHICON
) bmp
.CreateIconRef() , bmp
.GetWidth(), bmp
.GetHeight() ) ;
460 IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler
, wxBitmapHandler
)
462 bool wxICONResourceHandler::LoadFile(
463 wxBitmap
*bitmap
, const wxString
& name
, wxBitmapType
WXUNUSED(flags
),
464 int desiredWidth
, int desiredHeight
)
467 if ( icon
.LoadFile( name
, wxBITMAP_TYPE_ICON_RESOURCE
, desiredWidth
, desiredHeight
) )
469 bitmap
->CopyFromIcon( icon
) ;
470 return bitmap
->IsOk() ;