X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f1ca421b41579701556dee2d15af6c0256dc8495..c9ccc09c64f4c29d4667796bef7b507d9e8d25ed:/src/osx/carbon/icon.cpp?ds=sidebyside diff --git a/src/osx/carbon/icon.cpp b/src/osx/carbon/icon.cpp index ddd2dd43dc..d99c5a1e64 100644 --- a/src/osx/carbon/icon.cpp +++ b/src/osx/carbon/icon.cpp @@ -11,6 +11,8 @@ #include "wx/wxprec.h" +#if wxOSX_USE_COCOA_OR_CARBON + #include "wx/icon.h" #ifndef WX_PRECOMP @@ -48,6 +50,9 @@ private: IconRef m_iconRef; int m_width; int m_height; + + // We can (easily) copy m_iconRef so we don't implement the copy ctor. + wxDECLARE_NO_COPY_CLASS(wxIconRefData); }; @@ -122,9 +127,12 @@ wxGDIRefData *wxIcon::CreateGDIRefData() const return new wxIconRefData; } -wxGDIRefData *wxIcon::CloneGDIRefData(const wxGDIRefData *data) const +wxGDIRefData * +wxIcon::CloneGDIRefData(const wxGDIRefData * WXUNUSED(data)) const { - return new wxIconRefData(*static_cast(data)); + wxFAIL_MSG( wxS("Cloning icons is not implemented in wxCarbon.") ); + + return new wxIconRefData; } WXHICON wxIcon::GetHICON() const @@ -165,141 +173,288 @@ void wxIcon::SetHeight( int WXUNUSED(height) ) { } +// Load an icon based on resource name or filel name +// Return true on success, false otherwise bool wxIcon::LoadFile( const wxString& filename, wxBitmapType type, int desiredWidth, int desiredHeight ) +{ + if( type == wxBITMAP_TYPE_ICON_RESOURCE ) + { + if( LoadIconFromSystemResource( filename, desiredWidth, desiredHeight ) ) + return true; + else + return LoadIconFromBundleResource( filename, desiredWidth, desiredHeight ); + } + else if( type == wxBITMAP_TYPE_ICON ) + { + return LoadIconFromFile( filename, desiredWidth, desiredHeight ); + } + else + { + return LoadIconAsBitmap( filename, type, desiredWidth, desiredHeight ); + } +} + +// Load a well known system icon by its wxWidgets identifier +// Returns true on success, false otherwise +bool wxIcon::LoadIconFromSystemResource(const wxString& resourceName, int desiredWidth, int desiredHeight) { UnRef(); - if ( type == wxBITMAP_TYPE_ICON_RESOURCE ) + OSType theId = 0 ; + + if ( resourceName == wxT("wxICON_INFORMATION") ) { - OSType theId = 0 ; + theId = kAlertNoteIcon ; + } + else if ( resourceName == wxT("wxICON_QUESTION") ) + { + theId = kAlertCautionIcon ; + } + else if ( resourceName == wxT("wxICON_WARNING") ) + { + theId = kAlertCautionIcon ; + } + else if ( resourceName == wxT("wxICON_ERROR") ) + { + theId = kAlertStopIcon ; + } + else if ( resourceName == wxT("wxICON_FOLDER") ) + { + theId = kGenericFolderIcon ; + } + else if ( resourceName == wxT("wxICON_FOLDER_OPEN") ) + { + theId = kOpenFolderIcon ; + } + else if ( resourceName == wxT("wxICON_NORMAL_FILE") ) + { + theId = kGenericDocumentIcon ; + } + else if ( resourceName == wxT("wxICON_EXECUTABLE_FILE") ) + { + theId = kGenericApplicationIcon ; + } + else if ( resourceName == wxT("wxICON_CDROM") ) + { + theId = kGenericCDROMIcon ; + } + else if ( resourceName == wxT("wxICON_FLOPPY") ) + { + theId = kGenericFloppyIcon ; + } + else if ( resourceName == wxT("wxICON_HARDDISK") ) + { + theId = kGenericHardDiskIcon ; + } + else if ( resourceName == wxT("wxICON_REMOVABLE") ) + { + theId = kGenericRemovableMediaIcon ; + } + else if ( resourceName == wxT("wxICON_DELETE") ) + { + theId = kToolbarDeleteIcon ; + } + else if ( resourceName == wxT("wxICON_GO_BACK") ) + { + theId = kBackwardArrowIcon ; + } + else if ( resourceName == wxT("wxICON_GO_FORWARD") ) + { + theId = kForwardArrowIcon ; + } + else if ( resourceName == wxT("wxICON_GO_HOME") ) + { + theId = kToolbarHomeIcon ; + } + else if ( resourceName == wxT("wxICON_HELP_SETTINGS") ) + { + theId = kGenericFontIcon ; + } + else if ( resourceName == wxT("wxICON_HELP_PAGE") ) + { + theId = kGenericDocumentIcon ; + } - if ( filename == wxT("wxICON_INFORMATION") ) - { - theId = kAlertNoteIcon ; - } - else if ( filename == wxT("wxICON_QUESTION") ) - { - theId = kAlertCautionIcon ; - } - else if ( filename == wxT("wxICON_WARNING") ) - { - theId = kAlertCautionIcon ; - } - else if ( filename == wxT("wxICON_ERROR") ) - { - theId = kAlertStopIcon ; - } - else if ( filename == wxT("wxICON_FOLDER") ) - { - theId = kGenericFolderIcon ; - } - else if ( filename == wxT("wxICON_FOLDER_OPEN") ) - { - theId = kOpenFolderIcon ; - } - else if ( filename == wxT("wxICON_NORMAL_FILE") ) + if ( theId != 0 ) + { + IconRef iconRef = NULL ; + verify_noerr( GetIconRef( kOnSystemDisk, kSystemIconsCreator, theId, &iconRef ) ) ; + if ( iconRef ) { - theId = kGenericDocumentIcon ; + m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ) ; + return true ; } - else + } + + return false; +} + +// Load an icon of type 'icns' by resource by name +// The resource must exist in one of the currently accessible bundles +// (usually this means the application bundle for the current application) +// Return true on success, false otherwise +bool wxIcon::LoadIconFromBundleResource(const wxString& resourceName, int desiredWidth, int desiredHeight) +{ + UnRef(); + + IconRef iconRef = NULL ; + + // first look in the resource fork + if ( iconRef == NULL ) + { + Str255 theName ; + + wxMacStringToPascal( resourceName , theName ) ; + Handle resHandle = GetNamedResource( 'icns' , theName ) ; + if ( resHandle != 0L ) { - IconRef iconRef = NULL ; + IconFamilyHandle iconFamily = (IconFamilyHandle) resHandle ; + OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); - // first look in the resource fork - if ( iconRef == NULL ) + if ( err != noErr ) { - Str255 theName ; - - wxMacStringToPascal( filename , theName ) ; - Handle resHandle = GetNamedResource( 'icns' , theName ) ; - if ( resHandle != 0L ) - { - IconFamilyHandle iconFamily = (IconFamilyHandle) resHandle ; - HLock((Handle) iconFamily); - OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); - HUnlock((Handle) iconFamily); - if ( err != noErr ) - { - wxFAIL_MSG("Error when constructing icon ref"); - } - - ReleaseResource( resHandle ) ; - } - } - if ( iconRef == NULL ) - { - // TODO add other attempts to load it from files etc here + wxFAIL_MSG("Error when constructing icon ref"); } - if ( iconRef ) - { - m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ) ; - return true ; - } + + ReleaseResource( resHandle ) ; } + } + if ( iconRef == NULL ) + { + wxCFStringRef name(resourceName); + FSRef iconFSRef; + + wxCFRef iconURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), name, CFSTR("icns"), NULL)); - if ( theId != 0 ) + if (CFURLGetFSRef(iconURL, &iconFSRef)) { - IconRef iconRef = NULL ; - verify_noerr( GetIconRef( kOnSystemDisk, kSystemIconsCreator, theId, &iconRef ) ) ; - if ( iconRef ) + // Get a handle on the icon family + IconFamilyHandle iconFamily; + OSStatus err = ReadIconFromFSRef( &iconFSRef, &iconFamily ); + + if ( err == noErr ) { - m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ) ; - - return true ; + err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); } + ReleaseResource( (Handle) iconFamily ); } + } - return false ; + if ( iconRef ) + { + m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ); + return true; } - else + + return false; +} + +// Load an icon from an icon file using the underlying OS X API +// The icon file must be in a format understood by the OS +// Return true for success, false otherwise +bool wxIcon::LoadIconFromFile(const wxString& filename, int desiredWidth, int desiredHeight) +{ + UnRef(); + + OSStatus err; + bool result = false; + + // Get a file system reference + FSRef fsRef; + err = FSPathMakeRef( (const wxUint8*)filename.utf8_str().data(), &fsRef, NULL ); + + if( err != noErr ) + return false; + + // Get a handle on the icon family + IconFamilyHandle iconFamily; + err = ReadIconFromFSRef( &fsRef, &iconFamily ); + + if( err != noErr ) + return false; + + // Get the icon reference itself + IconRef iconRef; + err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); + + if( err == noErr ) { - wxBitmapHandler *handler = wxBitmap::FindHandler( type ); + // If everthing is OK, assign m_refData + m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ); + result = true; + } - if ( handler ) - { - wxBitmap bmp ; - if ( handler->LoadFile( &bmp , filename, type, desiredWidth, desiredHeight )) - { - CopyFromBitmap( bmp ) ; + // Release the iconFamily before returning + ReleaseResource( (Handle) iconFamily ); + return result; +} - return true ; - } +// Load an icon from a file using functionality from wxWidgets +// A suitable bitmap handler (or image handler) must be available +// Return true on success, false otherwise +bool wxIcon::LoadIconAsBitmap(const wxString& filename, wxBitmapType type, int desiredWidth, int desiredHeight) +{ + UnRef(); - return false ; - } - else + wxBitmapHandler *handler = wxBitmap::FindHandler( type ); + + if ( handler ) + { + wxBitmap bmp ; + if ( handler->LoadFile( &bmp , filename, type, desiredWidth, desiredHeight )) { + CopyFromBitmap( bmp ) ; + return true ; + } + } + #if wxUSE_IMAGE - wxImage loadimage( filename, type ); - if (loadimage.Ok()) - { - if ( desiredWidth == -1 ) - desiredWidth = loadimage.GetWidth() ; - if ( desiredHeight == -1 ) - desiredHeight = loadimage.GetHeight() ; - if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() ) - loadimage.Rescale( desiredWidth , desiredHeight ) ; + else + { + wxImage loadimage( filename, type ); + if (loadimage.Ok()) + { + if ( desiredWidth == -1 ) + desiredWidth = loadimage.GetWidth() ; + if ( desiredHeight == -1 ) + desiredHeight = loadimage.GetHeight() ; + if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() ) + loadimage.Rescale( desiredWidth , desiredHeight ) ; - wxBitmap bmp( loadimage ); - CopyFromBitmap( bmp ) ; + wxBitmap bmp( loadimage ); + CopyFromBitmap( bmp ) ; - return true; - } -#endif + return true; } } - return true ; +#endif + + return false; } + void wxIcon::CopyFromBitmap( const wxBitmap& bmp ) { UnRef() ; // as the bitmap owns that ref, we have to acquire it as well - IconRef iconRef = bmp.CreateIconRef() ; - m_refData = new wxIconRefData( (WXHICON) iconRef, bmp.GetWidth(), bmp.GetHeight() ) ; + + int w = bmp.GetWidth() ; + int h = bmp.GetHeight() ; + int sz = wxMax( w , h ) ; + + if ( sz == 24 || sz == 64 ) + { + wxBitmap scaleBmp( bmp.ConvertToImage().Scale( w * 2 , h * 2 ) ) ; + m_refData = new wxIconRefData( (WXHICON) scaleBmp.CreateIconRef(), bmp.GetWidth(), bmp.GetHeight() ) ; + } + else + { + m_refData = new wxIconRefData( (WXHICON) bmp.CreateIconRef() , bmp.GetWidth(), bmp.GetHeight() ) ; + } + } IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler) @@ -309,9 +464,13 @@ bool wxICONResourceHandler::LoadFile( int desiredWidth, int desiredHeight ) { wxIcon icon ; - icon.LoadFile( name , wxBITMAP_TYPE_ICON_RESOURCE , desiredWidth , desiredHeight ) ; - bitmap->CopyFromIcon( icon ) ; - - return bitmap->Ok() ; + if ( icon.LoadFile( name , wxBITMAP_TYPE_ICON_RESOURCE , desiredWidth , desiredHeight ) ) + { + bitmap->CopyFromIcon( icon ) ; + return bitmap->Ok() ; + } + return false; } +#endif +