From: David Elliott Date: Fri, 20 Jul 2007 04:06:26 +0000 (+0000) Subject: Rework the wxCusor ctor taking wx stock number to provide as many cursors as X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/69659fd770f615210efac4b4fa741b3ad6223616 Rework the wxCusor ctor taking wx stock number to provide as many cursors as possible by using the system cursors first, a set of built-in cursors copied from wxMac if a system cursor was not found, and a normal cursor otherwise. Fixes lack of wxCURSOR_HAND and makes the code easier to follow by clearly showing which cursors are and are not available from each source. Copyright 2007, Software 2000 Ltd. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47581 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/cocoa/cursor.mm b/src/cocoa/cursor.mm index 502ec33cec..7f3ec31b19 100644 --- a/src/cocoa/cursor.mm +++ b/src/cocoa/cursor.mm @@ -17,11 +17,13 @@ #ifndef WX_PRECOMP #include "wx/icon.h" + #include "wx/log.h" #endif //WX_PRECOMP #import #import #include "wx/cocoa/string.h" +#include "wx/cocoa/autorelease.h" IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap) @@ -182,15 +184,12 @@ ClassicCursor gMacCursors[kwxCursorLast+1] = // End of data copied from src/mac/carbon/cursor.cpp /////////////////////////////////////////////////////////////////////////// -/* wxStockCursor +/* NSCursorCreateWithPrivateId * Returns a newly allocated (i.e. retainCount == 1) NSCursor based on the * classic Mac OS cursor data in this source file. This allows us to * implement the "stock" wxWidgets cursors which aren't present in Cocoa. - * FIXME: This function should be static. - * FIXME: This function should use "Alloc" in preference to "Get" to follow - * the proper Cocoa naming conventions. */ -NSCursor* wxGetStockCursor( short sIndex ) +static inline NSCursor* NSCursorCreateWithPrivateId(short sIndex) { ClassicCursor* pCursor = &gMacCursors[sIndex]; @@ -260,6 +259,13 @@ NSCursor* wxGetStockCursor( short sIndex ) return theCursor; } +// TODO: Remove in trunk.. needed for 2.8 +NSCursor* wxGetStockCursor( short sIndex ) +{ + wxLogDebug("Please do not call wxGetStockCursor."); + return NSCursorCreateWithPrivateId(sIndex); +} + wxCursorRefData::wxCursorRefData() : m_width(32), m_height(32), m_hCursor(nil) { @@ -309,133 +315,129 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho [theImage release]; } -// Cursors by stock number -wxCursor::wxCursor(int cursor_type) -{ - m_refData = new wxCursorRefData; - - switch (cursor_type) - { - case wxCURSOR_IBEAM: - M_CURSORDATA->m_hCursor = [[NSCursor IBeamCursor] retain]; - break; - case wxCURSOR_ARROW: - M_CURSORDATA->m_hCursor = [[NSCursor arrowCursor] retain]; - break; -/* TODO: - case wxCURSOR_COPY_ARROW: - M_CURSORDATA->m_themeCursor = kThemeCopyArrowCursor ; - break; - case wxCURSOR_WAIT: - M_CURSORDATA->m_themeCursor = kThemeWatchCursor ; - break; - case wxCURSOR_CROSS: - M_CURSORDATA->m_themeCursor = kThemeCrossCursor; - break; - case wxCURSOR_SIZENWSE: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorSizeNWSE); - } - break; -*/ - case wxCURSOR_SIZENESW: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorSizeNESW); - } - break; -/* TODO: - case wxCURSOR_SIZEWE: - { - M_CURSORDATA->m_themeCursor = kThemeResizeLeftRightCursor; - } - break; -*/ - case wxCURSOR_SIZENS: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorSizeNS); - } - break; - case wxCURSOR_SIZING: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorSize); - } - break; -/* TODO: - case wxCURSOR_HAND: - { - M_CURSORDATA->m_themeCursor = kThemePointingHandCursor; - } - break; -*/ - case wxCURSOR_BULLSEYE: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorBullseye); - } - break; - case wxCURSOR_PENCIL: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorPencil); - } - break; - case wxCURSOR_MAGNIFIER: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorMagnifier); - } - break; - case wxCURSOR_NO_ENTRY: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorNoEntry); - } - break; -/* TODO: - case wxCURSOR_WATCH: - { - M_CURSORDATA->m_themeCursor = kThemeWatchCursor; - break; - } -*/ - case wxCURSOR_PAINT_BRUSH: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorPaintBrush); - break; - } - case wxCURSOR_POINT_LEFT: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorPointLeft); - break; - } - case wxCURSOR_POINT_RIGHT: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorPointRight); - break; - } - case wxCURSOR_QUESTION_ARROW: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorQuestionArrow); - break; - } - case wxCURSOR_BLANK: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorBlank); - break; - } - case wxCURSOR_RIGHT_ARROW: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorRightArrow); - break; - } - case wxCURSOR_SPRAYCAN: - { - M_CURSORDATA->m_hCursor = wxGetStockCursor(kwxCursorRoller); - break; +// Returns a system cursor given the NSCursor class method selector or +// nil if NSCursor does not respond to the message. +// For example, OS X before 10.3 won't respond to pointingHandCursor. +static inline NSCursor* GetSystemCursorWithSelector(SEL cursorSelector) +{ + if([NSCursor respondsToSelector: cursorSelector]) + return [NSCursor performSelector: cursorSelector]; + else + return nil; +} + +// Please maintain order as if this were an array keyed on wxStockCursor +static inline SEL GetCursorSelectorForStockCursor(int stock_cursor_id) +{ + switch(stock_cursor_id) + { + case wxCURSOR_ARROW: return @selector(arrowCursor); + case wxCURSOR_RIGHT_ARROW: break; + case wxCURSOR_BULLSEYE: break; + case wxCURSOR_CHAR: break; + case wxCURSOR_CROSS: return @selector(crosshairCursor); + case wxCURSOR_HAND: return @selector(pointingHandCursor); + case wxCURSOR_IBEAM: return @selector(IBeamCursor); + case wxCURSOR_LEFT_BUTTON: break; + case wxCURSOR_MAGNIFIER: break; + case wxCURSOR_MIDDLE_BUTTON: break; + case wxCURSOR_NO_ENTRY: break; + case wxCURSOR_PAINT_BRUSH: break; + case wxCURSOR_PENCIL: break; + case wxCURSOR_POINT_LEFT: break; + case wxCURSOR_POINT_RIGHT: break; + case wxCURSOR_QUESTION_ARROW: break; + case wxCURSOR_RIGHT_BUTTON: break; + case wxCURSOR_SIZENESW: break; + case wxCURSOR_SIZENS: return @selector(resizeUpDownCursor); + case wxCURSOR_SIZENWSE: break; + case wxCURSOR_SIZEWE: return @selector(resizeLeftRightCursor); + case wxCURSOR_SIZING: break; + case wxCURSOR_SPRAYCAN: break; + case wxCURSOR_WAIT: break; + case wxCURSOR_WATCH: break; + case wxCURSOR_BLANK: break; + case wxCURSOR_ARROWWAIT: break; + default: break; + } + return NULL; +} + +// Please maintain order as if this were an array keyed on wxStockCursor +static inline int GetPrivateCursorIdForStockCursor(int stock_cursor_id) +{ + switch(stock_cursor_id) + { + case wxCURSOR_ARROW: break; // NSCursor + case wxCURSOR_RIGHT_ARROW: return kwxCursorRightArrow; + case wxCURSOR_BULLSEYE: return kwxCursorBullseye; + case wxCURSOR_CHAR: break; + case wxCURSOR_CROSS: break; // NSCursor + case wxCURSOR_HAND: break; // NSCursor (OS X >= 10.3) + case wxCURSOR_IBEAM: break; // NSCursor + case wxCURSOR_LEFT_BUTTON: break; + case wxCURSOR_MAGNIFIER: return kwxCursorMagnifier; + case wxCURSOR_MIDDLE_BUTTON: break; + case wxCURSOR_NO_ENTRY: return kwxCursorNoEntry; + case wxCURSOR_PAINT_BRUSH: return kwxCursorPaintBrush; + case wxCURSOR_PENCIL: return kwxCursorPencil; + case wxCURSOR_POINT_LEFT: return kwxCursorPointLeft; + case wxCURSOR_POINT_RIGHT: return kwxCursorPointRight; + case wxCURSOR_QUESTION_ARROW: return kwxCursorQuestionArrow; + case wxCURSOR_RIGHT_BUTTON: break; + case wxCURSOR_SIZENESW: return kwxCursorSizeNESW; + case wxCURSOR_SIZENS: return kwxCursorSizeNS; // also NSCursor + case wxCURSOR_SIZENWSE: return kwxCursorSizeNWSE; + case wxCURSOR_SIZEWE: break; // NSCursor + case wxCURSOR_SIZING: return kwxCursorSize; + case wxCURSOR_SPRAYCAN: return kwxCursorRoller; + case wxCURSOR_WAIT: break; + case wxCURSOR_WATCH: break; + case wxCURSOR_BLANK: return kwxCursorBlank; + case wxCURSOR_ARROWWAIT: break; + default: break; + } + return -1; +} + +// Cursors by stock number (enum wxStockCursor) +wxCursor::wxCursor(int stock_cursor_id) +{ + m_refData = new wxCursorRefData; + + M_CURSORDATA->m_hCursor = nil; + + wxCHECK_RET( stock_cursor_id > wxCURSOR_NONE && stock_cursor_id < wxCURSOR_MAX, + wxT("invalid cursor id in wxCursor() ctor") ); + + // Stage 1: Try a system cursor + SEL cursorSelector; + if( (cursorSelector = GetCursorSelectorForStockCursor(stock_cursor_id)) != NULL) + { + M_CURSORDATA->m_hCursor = [GetSystemCursorWithSelector(cursorSelector) retain]; + } + + // TODO: Provide a pointing hand for OS X < 10.3 if desired + + // Stage 2: Try one of the 'CURS'-style cursors + if(M_CURSORDATA->m_hCursor == nil) + { + int privateId; + if( (privateId = GetPrivateCursorIdForStockCursor(stock_cursor_id)) >= 0) + { // wxGetStockCursor is not a get method but an alloc method. + M_CURSORDATA->m_hCursor = NSCursorCreateWithPrivateId(privateId); } - case wxCURSOR_CHAR: - case wxCURSOR_LEFT_BUTTON: - case wxCURSOR_RIGHT_BUTTON: - case wxCURSOR_MIDDLE_BUTTON: - default: - break; } + + // Stage 3: Give up, complain, and use a normal arrow + if(M_CURSORDATA->m_hCursor == nil) + { + wxLogDebug("Could not find suitable cursor for wxStockCursor = %d. Using normal pointer.", stock_cursor_id); + M_CURSORDATA->m_hCursor = [[NSCursor arrowCursor] retain]; + } + + // This should never happen as the arrowCursor should always exist. + wxASSERT(M_CURSORDATA->m_hCursor != nil); } wxCursor::~wxCursor()