osx new layout
[wxWidgets.git] / src / osx / carbon / utilscocoa.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/carbon/utils.mm
3 // Purpose:     various cocoa mixin utility functions
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     1998-01-01
7 // RCS-ID:      $Id: utilscocoa.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright:   (c) Stefan Csomor
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxOSX_USE_COCOA_OR_CARBON
15 #include <Cocoa/Cocoa.h>
16 #else
17 #import <UIKit/UIKit.h>
18 #endif
19
20 #ifdef __WXMAC__
21 #include "wx/osx/private.h"
22 #endif
23
24 #ifdef __WXMAC__
25
26 #if wxOSX_USE_CARBON
27 bool wxMacInitCocoa()
28 {
29     bool cocoaLoaded = NSApplicationLoad();
30     wxASSERT_MSG(cocoaLoaded,wxT("Couldn't load Cocoa in Carbon Environment")) ;
31     return cocoaLoaded;
32 }
33 #endif
34
35 wxMacAutoreleasePool::wxMacAutoreleasePool()
36 {
37     m_pool = [[NSAutoreleasePool alloc] init];
38 }
39
40 wxMacAutoreleasePool::~wxMacAutoreleasePool()
41 {
42     [(NSAutoreleasePool*)m_pool release];
43 }
44
45 #endif
46
47 #if defined( __WXCOCOCA__ ) || wxOSX_USE_COCOA
48
49 CGContextRef wxMacGetContextFromCurrentNSContext()
50 {
51     CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext]
52                                           graphicsPort];
53     return context;
54 }
55
56 #endif
57
58 // ----------------------------------------------------------------------------
59 // NSObject Utils
60 // ----------------------------------------------------------------------------
61
62 void wxMacCocoaRelease( void* obj )
63 {
64     [(NSObject*)obj release];
65 }
66
67 void wxMacCocoaAutorelease( void* obj )
68 {
69     [(NSObject*)obj autorelease];
70 }
71
72 void wxMacCocoaRetain( void* obj )
73 {
74     [(NSObject*)obj retain];
75 }
76
77 #if wxOSX_USE_COCOA
78
79 // ----------------------------------------------------------------------------
80 // NSImage Utils
81 // ----------------------------------------------------------------------------
82
83 //  From "Cocoa Drawing Guide:Working with Images"
84 WX_NSImage  wxOSXCreateNSImageFromCGImage( CGImageRef image )
85 {
86     NSRect      imageRect    = NSMakeRect(0.0, 0.0, 0.0, 0.0);
87     
88     // Get the image dimensions.
89     imageRect.size.height = CGImageGetHeight(image);
90     imageRect.size.width = CGImageGetWidth(image);
91     
92     // Create a new image to receive the Quartz image data.
93     NSImage  *newImage = [[NSImage alloc] initWithSize:imageRect.size]; 
94     [newImage lockFocus];
95     
96     // Get the Quartz context and draw.
97     CGContextRef  imageContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
98     CGContextDrawImage( imageContext, *(CGRect*)&imageRect, image );
99     [newImage unlockFocus];
100     
101     /*
102         // Create a bitmap rep from the image...
103         NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
104         // Create an NSImage and add the bitmap rep to it...
105         NSImage *image = [[NSImage alloc] init];
106         [image addRepresentation:bitmapRep];
107         [bitmapRep release];
108     */
109     [newImage autorelease];
110     return( newImage );
111 }
112
113 // ----------------------------------------------------------------------------
114 // NSCursor Utils
115 // ----------------------------------------------------------------------------
116
117 // copied from cursor.mm
118
119 static NSCursor* wxGetStockCursor( short sIndex )
120 {
121     ClassicCursor* pCursor = &gMacCursors[sIndex];
122
123     //Classic mac cursors are 1bps 16x16 black and white with a
124     //identical mask that is 1 for on and 0 for off
125     NSImage *theImage = [[NSImage alloc] initWithSize:NSMakeSize(16.0,16.0)];
126
127     //NSCursor takes an NSImage takes a number of Representations - here
128     //we need only one for the raw data
129     NSBitmapImageRep *theRep =
130     [[NSBitmapImageRep alloc]
131       initWithBitmapDataPlanes:nil  // Allocate the buffer for us :)
132       pixelsWide:16
133       pixelsHigh:16
134       bitsPerSample:1
135       samplesPerPixel:2
136       hasAlpha:YES                  // Well, more like a mask...
137       isPlanar:NO
138       colorSpaceName:NSCalibratedWhiteColorSpace // Normal B/W - 0 black 1 white
139       bytesPerRow:0     // I don't care - figure it out for me :)
140       bitsPerPixel:2];  // bitsPerSample * samplesPerPixel
141
142     //unsigned int is better to put data in then a void*
143     //note that working with bitfields would be a lot better here -
144     //but since it breaks some compilers...
145     wxUint32 *data = (wxUint32 *)[theRep bitmapData];
146
147     //traverse through the bitmap data
148     for (int i = 0; i < 16; ++i)
149     {
150         //bit alpha bit alpha ... :D
151
152         //Notice the = instead of |= -
153         //this is to avoid doing a memset earlier
154         data[i] = 0;
155
156         //do the rest of those bits and alphas :)
157         for (int shift = 0; shift < 32; ++shift)
158         {
159             const int bit = 1 << (shift >> 1);
160             data[i] |= ( !!( (pCursor->mask[i] & bit) ) ) << shift;
161             data[i] |= ( !( (pCursor->bits[i] & bit) ) ) << ++shift;
162         }
163     }
164
165     //add the representation (data) to the image
166     [theImage addRepresentation:theRep];
167
168     //create the new cursor
169     NSCursor* theCursor =  [[NSCursor alloc]  initWithImage:theImage
170                                     hotSpot:NSMakePoint(pCursor->hotspot[1], pCursor->hotspot[0])
171                             ];
172
173     //do the usual cleanups
174     [theRep release];
175     [theImage release];
176
177     //return the new cursor
178     return theCursor;
179 }
180
181 WX_NSCursor wxMacCocoaCreateStockCursor( int cursor_type )
182 {
183     WX_NSCursor cursor = nil;
184     switch (cursor_type)
185     {
186     case wxCURSOR_COPY_ARROW:
187         cursor = [[NSCursor arrowCursor] retain];
188         break;
189
190     case wxCURSOR_WATCH:
191     case wxCURSOR_WAIT:
192         // should be displayed by the system when things are running
193         cursor = [[NSCursor arrowCursor] retain];
194         break;
195
196     case wxCURSOR_IBEAM:
197         cursor = [[NSCursor IBeamCursor] retain];
198         break;
199
200     case wxCURSOR_CROSS:
201         cursor = [[NSCursor crosshairCursor] retain];
202         break;
203
204     case wxCURSOR_SIZENWSE:
205         cursor = wxGetStockCursor(kwxCursorSizeNWSE);
206         break;
207
208     case wxCURSOR_SIZENESW:
209         cursor = wxGetStockCursor(kwxCursorSizeNESW);
210         break;
211
212     case wxCURSOR_SIZEWE:
213         cursor = [[NSCursor resizeLeftRightCursor] retain];
214         break;
215
216     case wxCURSOR_SIZENS:
217         cursor = [[NSCursor resizeUpDownCursor] retain];
218         break;
219
220     case wxCURSOR_SIZING:
221         cursor = wxGetStockCursor(kwxCursorSize);
222         break;
223
224     case wxCURSOR_HAND:
225         cursor = [[NSCursor pointingHandCursor] retain];
226         break;
227
228     case wxCURSOR_BULLSEYE:
229         cursor = wxGetStockCursor(kwxCursorBullseye);
230         break;
231
232     case wxCURSOR_PENCIL:
233         cursor = wxGetStockCursor(kwxCursorPencil);
234         break;
235
236     case wxCURSOR_MAGNIFIER:
237         cursor = wxGetStockCursor(kwxCursorMagnifier);
238         break;
239
240     case wxCURSOR_NO_ENTRY:
241         cursor = wxGetStockCursor(kwxCursorNoEntry);
242         break;
243
244     case wxCURSOR_PAINT_BRUSH:
245         cursor = wxGetStockCursor(kwxCursorPaintBrush);
246         break;
247
248     case wxCURSOR_POINT_LEFT:
249         cursor = wxGetStockCursor(kwxCursorPointLeft);
250         break;
251
252     case wxCURSOR_POINT_RIGHT:
253         cursor = wxGetStockCursor(kwxCursorPointRight);
254         break;
255
256     case wxCURSOR_QUESTION_ARROW:
257         cursor = wxGetStockCursor(kwxCursorQuestionArrow);
258         break;
259
260     case wxCURSOR_BLANK:
261         cursor = wxGetStockCursor(kwxCursorBlank);
262         break;
263
264     case wxCURSOR_RIGHT_ARROW:
265         cursor = wxGetStockCursor(kwxCursorRightArrow);
266         break;
267
268     case wxCURSOR_SPRAYCAN:
269         cursor = wxGetStockCursor(kwxCursorRoller);
270         break;
271
272     case wxCURSOR_CHAR:
273     case wxCURSOR_ARROW:
274     case wxCURSOR_LEFT_BUTTON:
275     case wxCURSOR_RIGHT_BUTTON:
276     case wxCURSOR_MIDDLE_BUTTON:
277     default:
278         cursor = [[NSCursor arrowCursor] retain];
279         break;
280     }
281     return cursor;
282 }
283
284 //  C-based style wrapper routines around NSCursor
285 WX_NSCursor  wxMacCocoaCreateCursorFromCGImage( CGImageRef cgImageRef, float hotSpotX, float hotSpotY )
286 {
287     static BOOL    firstTime  = YES;
288     
289     if ( firstTime )
290     {
291         //  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
292         [[[NSWindow alloc] init] release];
293         firstTime = NO;
294     }
295     
296     NSImage    *nsImage  = wxOSXCreateNSImageFromCGImage( cgImageRef );
297     NSCursor  *cursor    = [[NSCursor alloc] initWithImage:nsImage hotSpot:NSMakePoint( hotSpotX, hotSpotY )];
298     
299     [nsImage release];
300     
301     return cursor;
302 }
303
304 void  wxMacCocoaSetCursor( WX_NSCursor cursor )
305 {
306     [cursor set];
307 }
308
309 void  wxMacCocoaHideCursor()
310 {
311     [NSCursor hide];
312 }
313
314 void  wxMacCocoaShowCursor()
315 {
316     [NSCursor unhide];
317 }
318
319 #endif
320