]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/icon.cpp
Don't call wxSafeYield() from wxGenericListCtrl::EditLabel().
[wxWidgets.git] / src / osx / carbon / icon.cpp
index a28dc190908a84e498159de6f998d7085b67f4bf..9e2fe589eea7ea1733011cdc19b317d35e3bca10 100644 (file)
@@ -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,28 +127,31 @@ 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<const wxIconRefData *>(data));
+    wxFAIL_MSG( wxS("Cloning icons is not implemented in wxCarbon.") );
+
+    return new wxIconRefData;
 }
 
 WXHICON wxIcon::GetHICON() const
 {
-    wxASSERT( Ok() ) ;
+    wxASSERT( IsOk() ) ;
 
     return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ;
 }
 
 int wxIcon::GetWidth() const
 {
-   wxCHECK_MSG( Ok(), -1, wxT("invalid icon") );
+   wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
 
    return M_ICONDATA->GetWidth();
 }
 
 int wxIcon::GetHeight() const
 {
-   wxCHECK_MSG( Ok(), -1, wxT("invalid icon") );
+   wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") );
 
    return M_ICONDATA->GetHeight();
 }
@@ -165,185 +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") )
+    {
+        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") )
     {
-        OSType theId = 0 ;
+        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") )
-        {
-            theId = kGenericDocumentIcon ;
-        }
-        else if ( filename == wxT("wxICON_EXECUTABLE_FILE") )
-        {
-            theId = kGenericApplicationIcon ;
-        }
-        else if ( filename == wxT("wxICON_CDROM") )
-        {
-            theId = kGenericCDROMIcon ;
-        }
-        else if ( filename == wxT("wxICON_FLOPPY") )
-        {
-            theId = kGenericFloppyIcon ;
-        }
-        else if ( filename == wxT("wxICON_HARDDISK") )
-        {
-            theId = kGenericHardDiskIcon ;
-        }
-        else if ( filename == wxT("wxICON_REMOVABLE") )
-        {
-            theId = kGenericRemovableMediaIcon ;
-        }
-        else if ( filename == wxT("wxICON_DELETE") )
-        {
-            theId = kToolbarDeleteIcon ;
-        }
-        else if ( filename == wxT("wxICON_GO_BACK") )
-        {
-            theId = kBackwardArrowIcon ;
-        }
-        else if ( filename == wxT("wxICON_GO_FORWARD") )
-        {
-            theId = kForwardArrowIcon ;
-        }
-        else if ( filename == wxT("wxICON_GO_HOME") )
-        {
-            theId = kToolbarHomeIcon ;
-        }
-        else if ( filename == wxT("wxICON_HELP_SETTINGS") )
-        {
-            theId = kGenericFontIcon ;
-        }
-        else if ( filename == wxT("wxICON_HELP_PAGE") )
+    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 )
-            {
-                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 )
+            if ( err != noErr )
             {
-                // 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<CFURLRef> 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 everything 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.IsOk())
+        {
+            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)
@@ -353,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->IsOk() ;
+    }
+    return false;
 }
 
+#endif
+