]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/utils.mm
39d2287aa283461c546fe07264c228c08daa83f4
[wxWidgets.git] / src / osx / cocoa / utils.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/utils.mm
3 // Purpose: various cocoa utility functions
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id: utils.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 #include "wx/wxprec.h"
15
16 #include "wx/utils.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/intl.h"
20 #include "wx/app.h"
21 #if wxUSE_GUI
22 #include "wx/toplevel.h"
23 #include "wx/font.h"
24 #endif
25 #endif
26
27 #include "wx/apptrait.h"
28
29 #include "wx/osx/private.h"
30
31 #if wxUSE_GUI
32 #if wxOSX_USE_COCOA_OR_CARBON
33 #include <CoreServices/CoreServices.h>
34 #include "wx/osx/dcclient.h"
35 #include "wx/osx/private/timer.h"
36 #endif
37 #endif // wxUSE_GUI
38
39 #if wxOSX_USE_COCOA
40
41 #if wxUSE_BASE
42
43 // Emit a beeeeeep
44 void wxBell()
45 {
46 NSBeep();
47 }
48
49 // ----------------------------------------------------------------------------
50 // Common Event Support
51 // ----------------------------------------------------------------------------
52
53 void wxMacWakeUp()
54 {
55 // TODO
56 }
57
58 #endif // wxUSE_BASE
59
60 #if wxUSE_GUI
61
62 @interface wxNSAppController : NSObject
63 {
64 }
65
66 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
67 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
68 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
69 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
70 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
71 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
72 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
73 @end
74
75 @implementation wxNSAppController
76
77 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
78 {
79 // let wx do this, not cocoa
80 return NO;
81 }
82
83 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
84 {
85 wxCFStringRef cf(wxCFRetain(filename));
86 wxTheApp->MacOpenFile(cf.AsString()) ;
87 return YES;
88 }
89
90 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
91 {
92 wxTheApp->MacNewFile() ;
93 return NO;
94 }
95
96 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
97 {
98 wxCFStringRef cf(wxCFRetain(filename));
99 wxTheApp->MacPrintFile(cf.AsString()) ;
100 return YES;
101 }
102
103 /*
104 Allowable return values are:
105 NSTerminateNow - it is ok to proceed with termination
106 NSTerminateCancel - the application should not be terminated
107 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
108 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
109 */
110 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
111 {
112 wxWindow* win = wxTheApp->GetTopWindow() ;
113 if ( win )
114 {
115 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
116 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
117 win->Close(true) ;
118 }
119 else
120 {
121 wxTheApp->ExitMainLoop() ;
122 }
123 return NSTerminateCancel;
124 }
125
126 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
127 {
128 wxTheApp->MacReopenApp() ;
129 return NO;
130 }
131
132 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
133 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
134 {
135 NSString* url = [[event descriptorAtIndex:1] stringValue];
136 wxCFStringRef cf(wxCFRetain(url));
137 wxTheApp->MacOpenURL(cf.AsString()) ;
138 }
139 @end
140
141 /*
142 allows ShowModal to work when using sheets.
143 see include/wx/osx/cocoa/private.h for more info
144 */
145 @implementation ModalDialogDelegate
146 - (id)init
147 {
148 [super init];
149 sheetFinished = NO;
150 resultCode = -1;
151 return self;
152 }
153
154 - (BOOL)finished
155 {
156 return sheetFinished;
157 }
158
159 - (int)code
160 {
161 return resultCode;
162 }
163
164 - (void)waitForSheetToFinish
165 {
166 while (!sheetFinished)
167 {
168 wxSafeYield();
169 }
170 }
171
172 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
173 {
174 resultCode = returnCode;
175 sheetFinished = YES;
176 [sheet orderOut: self];
177 }
178 @end
179
180 bool wxApp::DoInitGui()
181 {
182 [NSApplication sharedApplication];
183
184 if (!sm_isEmbedded)
185 {
186 wxNSAppController* controller = [[wxNSAppController alloc] init];
187 [[NSApplication sharedApplication] setDelegate:controller];
188
189 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
190 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
191 forEventClass:kInternetEventClass andEventID:kAEGetURL];
192 }
193 [NSApp finishLaunching];
194 return true;
195 }
196
197 void wxApp::DoCleanUp()
198 {
199 }
200
201 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
202 {
203 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
204 wxRect r = wxFromNSRect( NULL, displayRect );
205 if ( x )
206 *x = r.x;
207 if ( y )
208 *y = r.y;
209 if ( width )
210 *width = r.GetWidth();
211 if ( height )
212 *height = r.GetHeight();
213
214 }
215
216 void wxGetMousePosition( int* x, int* y )
217 {
218 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
219 if ( x )
220 *x = pt.x;
221 if ( y )
222 *y = pt.y;
223 };
224
225 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
226 {
227 return new wxOSXTimerImpl(timer);
228 }
229
230 int gs_wxBusyCursorCount = 0;
231 extern wxCursor gMacCurrentCursor;
232 wxCursor gMacStoredActiveCursor;
233
234 // Set the cursor to the busy cursor for all windows
235 void wxBeginBusyCursor(const wxCursor *cursor)
236 {
237 if (gs_wxBusyCursorCount++ == 0)
238 {
239 gMacStoredActiveCursor = gMacCurrentCursor;
240 cursor->MacInstall();
241
242 wxSetCursor(*cursor);
243 }
244 //else: nothing to do, already set
245 }
246
247 // Restore cursor to normal
248 void wxEndBusyCursor()
249 {
250 wxCHECK_RET( gs_wxBusyCursorCount > 0,
251 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
252
253 if (--gs_wxBusyCursorCount == 0)
254 {
255 gMacStoredActiveCursor.MacInstall();
256 gMacStoredActiveCursor = wxNullCursor;
257
258 wxSetCursor(wxNullCursor);
259 }
260 }
261
262 // true if we're between the above two calls
263 bool wxIsBusy()
264 {
265 return (gs_wxBusyCursorCount > 0);
266 }
267
268 void wxMacGlobalToLocal( WindowRef window , Point*pt )
269 {
270 }
271
272 void wxMacLocalToGlobal( WindowRef window , Point*pt )
273 {
274 }
275
276 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
277 {
278 // wxScreenDC is derived from wxWindowDC, so a screen dc will
279 // call this method when a Blit is performed with it as a source.
280 if (!m_window)
281 return wxNullBitmap;
282
283 wxSize sz = m_window->GetSize();
284
285 int left = subrect != NULL ? subrect->x : 0 ;
286 int top = subrect != NULL ? subrect->y : 0 ;
287 int width = subrect != NULL ? subrect->width : sz.x;
288 int height = subrect != NULL ? subrect->height : sz.y ;
289
290 NSRect rect = NSMakeRect(left, top, width, height );
291 NSView* view = (NSView*) m_window->GetHandle();
292 [view lockFocus];
293 // we use this method as other methods force a repaint, and this method can be
294 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
295 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
296 [view unlockFocus];
297
298 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
299
300 wxBitmap bitmap(CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
301 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
302 // since our context is upside down we dont use CGContextDrawImage
303 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
304 CGImageRelease(cgImageRef);
305 cgImageRef = NULL;
306 [rep release];
307
308 return bitmap;
309 }
310
311 #endif // wxUSE_GUI
312
313 #endif // wxOSX_USE_COCOA