PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ExtLibs/wxWidgets/src/osx/carbon/utilscocoa.mm

https://bitbucket.org/lennonchan/cafu
Objective C++ | 655 lines | 469 code | 106 blank | 80 comment | 50 complexity | 58ebc841ac45b9c9d3714ff3e318193e MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/osx/carbon/utilscocoa.mm
  3. // Purpose: various cocoa mixin utility functions
  4. // Author: Stefan Csomor
  5. // Modified by:
  6. // Created: 1998-01-01
  7. // RCS-ID: $Id$
  8. // Copyright: (c) Stefan Csomor
  9. // Licence: wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11. #include "wx/wxprec.h"
  12. #if wxOSX_USE_COCOA_OR_CARBON
  13. #include <Cocoa/Cocoa.h>
  14. #else
  15. #import <UIKit/UIKit.h>
  16. #endif
  17. #ifdef __WXMAC__
  18. #include "wx/osx/private.h"
  19. #endif
  20. #include "wx/fontutil.h"
  21. #if wxOSX_USE_COCOA
  22. #include "wx/cocoa/string.h"
  23. #endif
  24. #ifdef __WXMAC__
  25. #if wxOSX_USE_CARBON
  26. bool wxMacInitCocoa()
  27. {
  28. bool cocoaLoaded = NSApplicationLoad();
  29. wxASSERT_MSG(cocoaLoaded,wxT("Couldn't load Cocoa in Carbon Environment")) ;
  30. return cocoaLoaded;
  31. }
  32. #endif
  33. wxMacAutoreleasePool::wxMacAutoreleasePool()
  34. {
  35. m_pool = [[NSAutoreleasePool alloc] init];
  36. }
  37. wxMacAutoreleasePool::~wxMacAutoreleasePool()
  38. {
  39. [(NSAutoreleasePool*)m_pool release];
  40. }
  41. #endif
  42. #if wxOSX_USE_COCOA
  43. CGContextRef wxOSXGetContextFromCurrentContext()
  44. {
  45. CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext]
  46. graphicsPort];
  47. return context;
  48. }
  49. bool wxOSXLockFocus( WXWidget view)
  50. {
  51. return [view lockFocusIfCanDraw];
  52. }
  53. void wxOSXUnlockFocus( WXWidget view)
  54. {
  55. [view unlockFocus];
  56. }
  57. #endif
  58. #if wxOSX_USE_IPHONE
  59. CGContextRef wxOSXGetContextFromCurrentContext()
  60. {
  61. CGContextRef context = UIGraphicsGetCurrentContext();
  62. return context;
  63. }
  64. #endif
  65. // ----------------------------------------------------------------------------
  66. // NSObject Utils
  67. // ----------------------------------------------------------------------------
  68. void wxMacCocoaRelease( void* obj )
  69. {
  70. [(NSObject*)obj release];
  71. }
  72. void wxMacCocoaAutorelease( void* obj )
  73. {
  74. [(NSObject*)obj autorelease];
  75. }
  76. void* wxMacCocoaRetain( void* obj )
  77. {
  78. [(NSObject*)obj retain];
  79. return obj;
  80. }
  81. // ----------------------------------------------------------------------------
  82. // NSFont Utils
  83. // ----------------------------------------------------------------------------
  84. #if wxOSX_USE_COCOA
  85. wxFont::wxFont(WX_NSFont nsfont)
  86. {
  87. [nsfont retain];
  88. wxNativeFontInfo info;
  89. SetNativeInfoFromNSFont(nsfont, &info);
  90. Create(info);
  91. }
  92. void wxFont::SetNativeInfoFromNSFont(WX_NSFont theFont, wxNativeFontInfo* info)
  93. {
  94. if ( info->m_faceName.empty())
  95. {
  96. //Get more information about the user's chosen font
  97. NSFontTraitMask theTraits = [[NSFontManager sharedFontManager] traitsOfFont:theFont];
  98. int theFontWeight = [[NSFontManager sharedFontManager] weightOfFont:theFont];
  99. wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT;
  100. //Set the wx font to the appropriate data
  101. if(theTraits & NSFixedPitchFontMask)
  102. fontFamily = wxFONTFAMILY_TELETYPE;
  103. wxFontStyle fontstyle = wxFONTSTYLE_NORMAL;
  104. wxFontWeight fontweight = wxFONTWEIGHT_NORMAL;
  105. bool underlined = false;
  106. int size = (int) ([theFont pointSize]+0.5);
  107. if ( theFontWeight >= 9 )
  108. fontweight = wxFONTWEIGHT_BOLD ;
  109. else if ( theFontWeight < 5 )
  110. fontweight = wxFONTWEIGHT_LIGHT;
  111. else
  112. fontweight = wxFONTWEIGHT_NORMAL ;
  113. if ( theTraits & NSItalicFontMask )
  114. fontstyle = wxFONTSTYLE_ITALIC ;
  115. info->Init(size,fontFamily,fontstyle,fontweight,underlined,
  116. wxStringWithNSString([theFont familyName]), wxFONTENCODING_DEFAULT);
  117. }
  118. }
  119. WX_NSFont wxFont::OSXCreateNSFont(wxOSXSystemFont font, wxNativeFontInfo* info)
  120. {
  121. NSFont* nsfont = nil;
  122. switch( font )
  123. {
  124. case wxOSX_SYSTEM_FONT_NORMAL:
  125. nsfont = [NSFont systemFontOfSize:[NSFont systemFontSize]];
  126. break;
  127. case wxOSX_SYSTEM_FONT_BOLD:
  128. nsfont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
  129. break;
  130. case wxOSX_SYSTEM_FONT_SMALL:
  131. nsfont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
  132. break;
  133. case wxOSX_SYSTEM_FONT_SMALL_BOLD:
  134. nsfont = [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]];
  135. break;
  136. case wxOSX_SYSTEM_FONT_MINI:
  137. nsfont = [NSFont systemFontOfSize:
  138. [NSFont systemFontSizeForControlSize:NSMiniControlSize]];
  139. break;
  140. case wxOSX_SYSTEM_FONT_MINI_BOLD:
  141. nsfont = [NSFont boldSystemFontOfSize:
  142. [NSFont systemFontSizeForControlSize:NSMiniControlSize]];
  143. break;
  144. case wxOSX_SYSTEM_FONT_LABELS:
  145. nsfont = [NSFont labelFontOfSize:[NSFont labelFontSize]];
  146. break;
  147. case wxOSX_SYSTEM_FONT_VIEWS:
  148. nsfont = [NSFont controlContentFontOfSize:0];
  149. break;
  150. default:
  151. break;
  152. }
  153. [nsfont retain];
  154. SetNativeInfoFromNSFont(nsfont, info);
  155. return nsfont;
  156. }
  157. static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
  158. static const NSAffineTransformStruct kSlantNSTransformStruct = { 1, 0, tan(DegToRad(11)), 1, 0, 0 };
  159. WX_NSFont wxFont::OSXCreateNSFont(const wxNativeFontInfo* info)
  160. {
  161. NSFont* nsFont;
  162. int weight = 5;
  163. NSFontTraitMask traits = 0;
  164. if (info->m_weight == wxFONTWEIGHT_BOLD)
  165. {
  166. traits |= NSBoldFontMask;
  167. weight = 9;
  168. }
  169. else if (info->m_weight == wxFONTWEIGHT_LIGHT)
  170. weight = 3;
  171. if (info->m_style == wxFONTSTYLE_ITALIC || info->m_style == wxFONTSTYLE_SLANT)
  172. traits |= NSItalicFontMask;
  173. nsFont = [[NSFontManager sharedFontManager] fontWithFamily:wxCFStringRef(info->m_faceName).AsNSString()
  174. traits:traits weight:weight size:info->m_pointSize];
  175. if ( nsFont == nil )
  176. {
  177. NSFontTraitMask remainingTraits = traits;
  178. nsFont = [[NSFontManager sharedFontManager] fontWithFamily:wxCFStringRef(info->m_faceName).AsNSString()
  179. traits:0 weight:5 size:info->m_pointSize];
  180. if ( nsFont == nil )
  181. {
  182. if ( info->m_weight == wxFONTWEIGHT_BOLD )
  183. {
  184. nsFont = [NSFont boldSystemFontOfSize:info->m_pointSize];
  185. remainingTraits &= ~NSBoldFontMask;
  186. }
  187. else
  188. nsFont = [NSFont systemFontOfSize:info->m_pointSize];
  189. }
  190. // fallback - if in doubt, let go of the bold attribute
  191. if ( nsFont && (remainingTraits & NSItalicFontMask) )
  192. {
  193. NSFont* nsFontWithTraits = nil;
  194. if ( remainingTraits & NSBoldFontMask)
  195. {
  196. nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
  197. if ( nsFontWithTraits == nil )
  198. {
  199. nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
  200. if ( nsFontWithTraits != nil )
  201. remainingTraits &= ~NSItalicFontMask;
  202. }
  203. else
  204. {
  205. remainingTraits &= ~NSBoldFontMask;
  206. }
  207. }
  208. // the code below causes crashes, because fontDescriptorWithMatrix is not returning a valid font descriptor
  209. // it adds a NSCTFontMatrixAttribute as well which cannot be disposed of correctly by the autorelease pool
  210. // so at the moment we have to disable this and cannot synthesize italic fonts if they are not available on the system
  211. #if 0
  212. if ( remainingTraits & NSItalicFontMask )
  213. {
  214. if ( nsFontWithTraits == nil )
  215. nsFontWithTraits = nsFont;
  216. NSAffineTransform* transform = [NSAffineTransform transform];
  217. [transform setTransformStruct:kSlantNSTransformStruct];
  218. [transform scaleBy:info->m_pointSize];
  219. NSFontDescriptor* italicDesc = [[nsFontWithTraits fontDescriptor] fontDescriptorWithMatrix:transform];
  220. if ( italicDesc != nil )
  221. {
  222. NSFont* f = [NSFont fontWithDescriptor:italicDesc size:(CGFloat)(info->m_pointSize)];
  223. if ( f != nil )
  224. nsFontWithTraits = f;
  225. }
  226. }
  227. #endif
  228. if ( nsFontWithTraits != nil )
  229. nsFont = nsFontWithTraits;
  230. }
  231. }
  232. wxASSERT_MSG(nsFont != nil,wxT("Couldn't create nsFont")) ;
  233. wxMacCocoaRetain(nsFont);
  234. return nsFont;
  235. }
  236. #endif
  237. #if wxOSX_USE_IPHONE
  238. WX_UIFont wxFont::OSXCreateUIFont(wxOSXSystemFont font, wxNativeFontInfo* info)
  239. {
  240. UIFont* uifont;
  241. switch( font )
  242. {
  243. case wxOSX_SYSTEM_FONT_NORMAL:
  244. uifont = [UIFont systemFontOfSize:[UIFont systemFontSize]];
  245. break;
  246. case wxOSX_SYSTEM_FONT_BOLD:
  247. uifont = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
  248. break;
  249. case wxOSX_SYSTEM_FONT_MINI:
  250. case wxOSX_SYSTEM_FONT_SMALL:
  251. uifont = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
  252. break;
  253. case wxOSX_SYSTEM_FONT_MINI_BOLD:
  254. case wxOSX_SYSTEM_FONT_SMALL_BOLD:
  255. uifont = [UIFont boldSystemFontOfSize:[UIFont smallSystemFontSize]];
  256. break;
  257. case wxOSX_SYSTEM_FONT_VIEWS:
  258. case wxOSX_SYSTEM_FONT_LABELS:
  259. uifont = [UIFont systemFontOfSize:[UIFont labelFontSize]];
  260. break;
  261. default:
  262. break;
  263. }
  264. [uifont retain];
  265. if ( info->m_faceName.empty())
  266. {
  267. wxFontStyle fontstyle = wxFONTSTYLE_NORMAL;
  268. wxFontWeight fontweight = wxFONTWEIGHT_NORMAL;
  269. bool underlined = false;
  270. int size = (int) ([uifont pointSize]+0.5);
  271. /*
  272. NSFontSymbolicTraits traits = [desc symbolicTraits];
  273. if ( traits & NSFontBoldTrait )
  274. fontweight = wxFONTWEIGHT_BOLD ;
  275. else
  276. fontweight = wxFONTWEIGHT_NORMAL ;
  277. if ( traits & NSFontItalicTrait )
  278. fontstyle = wxFONTSTYLE_ITALIC ;
  279. */
  280. wxCFStringRef fontname( wxCFRetain([uifont familyName]) );
  281. info->Init(size,wxFONTFAMILY_DEFAULT,fontstyle,fontweight,underlined,
  282. fontname.AsString(), wxFONTENCODING_DEFAULT);
  283. }
  284. return uifont;
  285. }
  286. WX_UIFont wxFont::OSXCreateUIFont(const wxNativeFontInfo* info)
  287. {
  288. UIFont* uiFont;
  289. uiFont = [UIFont fontWithName:wxCFStringRef(info->m_faceName).AsNSString() size:info->m_pointSize];
  290. wxMacCocoaRetain(uiFont);
  291. return uiFont;
  292. }
  293. #endif
  294. // ----------------------------------------------------------------------------
  295. // NSImage Utils
  296. // ----------------------------------------------------------------------------
  297. #if wxOSX_USE_IPHONE
  298. WX_UIImage wxOSXGetUIImageFromCGImage( CGImageRef image )
  299. {
  300. UIImage *newImage = [UIImage imageWithCGImage:image];
  301. [newImage autorelease];
  302. return( newImage );
  303. }
  304. wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &client, const wxSize& size)
  305. {
  306. #if 1
  307. // unfortunately this only accesses images in the app bundle, not the system wide globals
  308. wxCFStringRef cfname(name);
  309. return wxBitmap( [[UIImage imageNamed:cfname.AsNSString()] CGImage] );
  310. #else
  311. return wxBitmap();
  312. #endif
  313. }
  314. #endif
  315. #if wxOSX_USE_COCOA
  316. wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &WXUNUSED(client), const wxSize& WXUNUSED(size))
  317. {
  318. wxCFStringRef cfname(name);
  319. wxCFRef<CGImageRef> image( wxOSXCreateCGImageFromNSImage([NSImage imageNamed:cfname.AsNSString()]) );
  320. return wxBitmap( image );
  321. }
  322. // From "Cocoa Drawing Guide:Working with Images"
  323. WX_NSImage wxOSXGetNSImageFromCGImage( CGImageRef image )
  324. {
  325. NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
  326. // Get the image dimensions.
  327. imageRect.size.height = CGImageGetHeight(image);
  328. imageRect.size.width = CGImageGetWidth(image);
  329. // Create a new image to receive the Quartz image data.
  330. NSImage *newImage = [[NSImage alloc] initWithSize:imageRect.size];
  331. [newImage lockFocus];
  332. // Get the Quartz context and draw.
  333. CGContextRef imageContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
  334. CGContextDrawImage( imageContext, *(CGRect*)&imageRect, image );
  335. [newImage unlockFocus];
  336. /*
  337. // Create a bitmap rep from the image...
  338. NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
  339. // Create an NSImage and add the bitmap rep to it...
  340. NSImage *image = [[NSImage alloc] init];
  341. [image addRepresentation:bitmapRep];
  342. [bitmapRep release];
  343. */
  344. [newImage autorelease];
  345. return( newImage );
  346. }
  347. CGImageRef wxOSXCreateCGImageFromNSImage( WX_NSImage nsimage )
  348. {
  349. // based on http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg18065.html
  350. CGImageRef image = NULL;
  351. if (nsimage != nil)
  352. {
  353. NSSize imageSize = [nsimage size];
  354. CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, 0, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst);
  355. NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
  356. [NSGraphicsContext saveGraphicsState];
  357. [NSGraphicsContext setCurrentContext:nsGraphicsContext];
  358. [[NSColor whiteColor] setFill];
  359. NSRectFill(NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height));
  360. [nsimage drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
  361. [NSGraphicsContext setCurrentContext:nsGraphicsContext];
  362. image = CGBitmapContextCreateImage(context);
  363. CFRelease(context);
  364. }
  365. return image;
  366. }
  367. // ----------------------------------------------------------------------------
  368. // NSCursor Utils
  369. // ----------------------------------------------------------------------------
  370. // copied from cursor.mm
  371. static NSCursor* wxGetStockCursor( short sIndex )
  372. {
  373. ClassicCursor* pCursor = &gMacCursors[sIndex];
  374. //Classic mac cursors are 1bps 16x16 black and white with a
  375. //identical mask that is 1 for on and 0 for off
  376. NSImage *theImage = [[NSImage alloc] initWithSize:NSMakeSize(16.0,16.0)];
  377. //NSCursor takes an NSImage takes a number of Representations - here
  378. //we need only one for the raw data
  379. NSBitmapImageRep *theRep = [[NSBitmapImageRep alloc]
  380. initWithBitmapDataPlanes: NULL // Tell Cocoa to allocate the planes for us.
  381. pixelsWide: 16 // All classic cursors are 16x16
  382. pixelsHigh: 16
  383. bitsPerSample: 1 // All classic cursors are bitmaps with bitmasks
  384. samplesPerPixel: 2 // Sample 0:image 1:mask
  385. hasAlpha: YES // Identify last sample as a mask
  386. isPlanar: YES // Use a separate array for each sample
  387. colorSpaceName: NSCalibratedWhiteColorSpace // 0.0=black 1.0=white
  388. bytesPerRow: 2 // Rows in each plane are on 2-byte boundaries (no pad)
  389. bitsPerPixel: 1]; // same as bitsPerSample since data is planar
  390. // Ensure that Cocoa allocated 2 and only 2 of the 5 possible planes
  391. unsigned char *planes[5];
  392. [theRep getBitmapDataPlanes:planes];
  393. wxASSERT(planes[0] != NULL);
  394. wxASSERT(planes[1] != NULL);
  395. wxASSERT(planes[2] == NULL);
  396. wxASSERT(planes[3] == NULL);
  397. wxASSERT(planes[4] == NULL);
  398. // NOTE1: The Cursor's bits field is white=0 black=1.. thus the bitwise-not
  399. // Why not use NSCalibratedBlackColorSpace? Because that reverses the
  400. // sense of the alpha (mask) plane.
  401. // NOTE2: The mask data is 0=off 1=on
  402. // NOTE3: Cocoa asks for "premultiplied" color planes. Since we have a
  403. // 1-bit color plane and a 1-bit alpha plane we can just do a bitwise-and
  404. // on the two. The original cursor bitmaps have 0 (white actually) for
  405. // any masked-off pixels. Therefore every masked-off pixel would be wrong
  406. // since we bit-flip all of the picture bits. In practice, Cocoa doesn't
  407. // seem to care, but we are following the documentation.
  408. // Fill in the color (black/white) plane
  409. for(int i=0; i<16; ++i)
  410. {
  411. planes[0][2*i ] = (~pCursor->bits[i] & pCursor->mask[i]) >> 8 & 0xff;
  412. planes[0][2*i+1] = (~pCursor->bits[i] & pCursor->mask[i]) & 0xff;
  413. }
  414. // Fill in the alpha (i.e. mask) plane
  415. for(int i=0; i<16; ++i)
  416. {
  417. planes[1][2*i ] = pCursor->mask[i] >> 8 & 0xff;
  418. planes[1][2*i+1] = pCursor->mask[i] & 0xff;
  419. }
  420. //add the representation (data) to the image
  421. [theImage addRepresentation:theRep];
  422. //create the new cursor
  423. NSCursor* theCursor = [[NSCursor alloc] initWithImage:theImage
  424. hotSpot:NSMakePoint(pCursor->hotspot[1], pCursor->hotspot[0])
  425. ];
  426. //do the usual cleanups
  427. [theRep release];
  428. [theImage release];
  429. //return the new cursor
  430. return theCursor;
  431. }
  432. WX_NSCursor wxMacCocoaCreateStockCursor( int cursor_type )
  433. {
  434. WX_NSCursor cursor = nil;
  435. switch (cursor_type)
  436. {
  437. case wxCURSOR_COPY_ARROW:
  438. cursor = [[NSCursor arrowCursor] retain];
  439. break;
  440. case wxCURSOR_WATCH:
  441. case wxCURSOR_WAIT:
  442. // an arrow should be displayed by the system when things are running
  443. // according to the HIG
  444. // cursor = [[NSCursor arrowCursor] retain];
  445. // but for crossplatform compatibility we display a watch cursor
  446. cursor = wxGetStockCursor(kwxCursorWatch);
  447. break;
  448. case wxCURSOR_IBEAM:
  449. cursor = [[NSCursor IBeamCursor] retain];
  450. break;
  451. case wxCURSOR_CROSS:
  452. cursor = [[NSCursor crosshairCursor] retain];
  453. break;
  454. case wxCURSOR_SIZENWSE:
  455. cursor = wxGetStockCursor(kwxCursorSizeNWSE);
  456. break;
  457. case wxCURSOR_SIZENESW:
  458. cursor = wxGetStockCursor(kwxCursorSizeNESW);
  459. break;
  460. case wxCURSOR_SIZEWE:
  461. cursor = [[NSCursor resizeLeftRightCursor] retain];
  462. break;
  463. case wxCURSOR_SIZENS:
  464. cursor = [[NSCursor resizeUpDownCursor] retain];
  465. break;
  466. case wxCURSOR_SIZING:
  467. cursor = wxGetStockCursor(kwxCursorSize);
  468. break;
  469. case wxCURSOR_HAND:
  470. cursor = [[NSCursor pointingHandCursor] retain];
  471. break;
  472. case wxCURSOR_BULLSEYE:
  473. cursor = wxGetStockCursor(kwxCursorBullseye);
  474. break;
  475. case wxCURSOR_PENCIL:
  476. cursor = wxGetStockCursor(kwxCursorPencil);
  477. break;
  478. case wxCURSOR_MAGNIFIER:
  479. cursor = wxGetStockCursor(kwxCursorMagnifier);
  480. break;
  481. case wxCURSOR_NO_ENTRY:
  482. cursor = wxGetStockCursor(kwxCursorNoEntry);
  483. break;
  484. case wxCURSOR_PAINT_BRUSH:
  485. cursor = wxGetStockCursor(kwxCursorPaintBrush);
  486. break;
  487. case wxCURSOR_POINT_LEFT:
  488. cursor = wxGetStockCursor(kwxCursorPointLeft);
  489. break;
  490. case wxCURSOR_POINT_RIGHT:
  491. cursor = wxGetStockCursor(kwxCursorPointRight);
  492. break;
  493. case wxCURSOR_QUESTION_ARROW:
  494. cursor = wxGetStockCursor(kwxCursorQuestionArrow);
  495. break;
  496. case wxCURSOR_BLANK:
  497. cursor = wxGetStockCursor(kwxCursorBlank);
  498. break;
  499. case wxCURSOR_RIGHT_ARROW:
  500. cursor = wxGetStockCursor(kwxCursorRightArrow);
  501. break;
  502. case wxCURSOR_SPRAYCAN:
  503. cursor = wxGetStockCursor(kwxCursorRoller);
  504. break;
  505. case wxCURSOR_OPEN_HAND:
  506. cursor = [[NSCursor openHandCursor] retain];
  507. break;
  508. case wxCURSOR_CLOSED_HAND:
  509. cursor = [[NSCursor closedHandCursor] retain];
  510. break;
  511. case wxCURSOR_CHAR:
  512. case wxCURSOR_ARROW:
  513. case wxCURSOR_LEFT_BUTTON:
  514. case wxCURSOR_RIGHT_BUTTON:
  515. case wxCURSOR_MIDDLE_BUTTON:
  516. default:
  517. cursor = [[NSCursor arrowCursor] retain];
  518. break;
  519. }
  520. return cursor;
  521. }
  522. // C-based style wrapper routines around NSCursor
  523. WX_NSCursor wxMacCocoaCreateCursorFromCGImage( CGImageRef cgImageRef, float hotSpotX, float hotSpotY )
  524. {
  525. static BOOL firstTime = YES;
  526. if ( firstTime )
  527. {
  528. // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
  529. [[[NSWindow alloc] init] release];
  530. firstTime = NO;
  531. }
  532. NSImage *nsImage = wxOSXGetNSImageFromCGImage( cgImageRef );
  533. NSCursor *cursor = [[NSCursor alloc] initWithImage:nsImage hotSpot:NSMakePoint( hotSpotX, hotSpotY )];
  534. return cursor;
  535. }
  536. void wxMacCocoaSetCursor( WX_NSCursor cursor )
  537. {
  538. [cursor set];
  539. }
  540. void wxMacCocoaHideCursor()
  541. {
  542. [NSCursor hide];
  543. }
  544. void wxMacCocoaShowCursor()
  545. {
  546. [NSCursor unhide];
  547. }
  548. #endif