1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/utils.mm
3 // Purpose: various cocoa utility functions
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: utils.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
20 #include "wx/dialog.h"
21 #include "wx/toplevel.h"
26 #include "wx/apptrait.h"
28 #include "wx/osx/private.h"
31 #if wxOSX_USE_COCOA_OR_CARBON
32 #include <CoreServices/CoreServices.h>
33 #include "wx/osx/dcclient.h"
34 #include "wx/osx/private/timer.h"
52 @implementation wxNSAppController
54 - (void)applicationWillFinishLaunching:(NSNotification *)application {
55 wxUnusedVar(application);
58 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
61 wxCFStringRef cf(wxCFRetain(filename));
62 wxTheApp->MacOpenFile(cf.AsString()) ;
66 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
69 wxTheApp->MacNewFile() ;
73 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
76 wxCFStringRef cf(wxCFRetain(filename));
77 wxTheApp->MacPrintFile(cf.AsString()) ;
81 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
85 wxTheApp->MacReopenApp() ;
89 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
90 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
92 wxUnusedVar(replyEvent);
93 NSString* url = [[event descriptorAtIndex:1] stringValue];
94 wxCFStringRef cf(wxCFRetain(url));
95 wxTheApp->MacOpenURL(cf.AsString()) ;
99 Allowable return values are:
100 NSTerminateNow - it is ok to proceed with termination
101 NSTerminateCancel - the application should not be terminated
102 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
103 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
105 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
109 wxTheApp->OnQueryEndSession(event);
110 if ( event.GetVeto() )
111 return NSTerminateCancel;
113 return NSTerminateNow;
116 - (void)applicationWillTerminate:(NSNotification *)application {
117 wxUnusedVar(application);
119 event.SetCanVeto(false);
120 wxTheApp->OnEndSession(event);
123 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
126 // let wx do this, not cocoa
133 allows ShowModal to work when using sheets.
134 see include/wx/osx/cocoa/private.h for more info
136 @implementation ModalDialogDelegate
146 - (void)setImplementation: (wxDialog *)dialog
153 return sheetFinished;
161 - (void)waitForSheetToFinish
163 while (!sheetFinished)
169 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
171 wxUnusedVar(contextInfo);
172 resultCode = returnCode;
174 // NSAlerts don't need nor respond to orderOut
175 if ([sheet respondsToSelector:@selector(orderOut:)])
176 [sheet orderOut: self];
179 impl->ModalFinishedCallback(sheet, returnCode);
183 bool wxApp::DoInitGui()
185 wxMacAutoreleasePool pool;
186 [NSApplication sharedApplication];
190 wxNSAppController* controller = [[wxNSAppController alloc] init];
191 [NSApp setDelegate:controller];
193 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
194 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
195 forEventClass:kInternetEventClass andEventID:kAEGetURL];
197 // calling finishLaunching so early before running the loop seems to trigger some 'MenuManager compatibility' which leads
198 // to the duplication of menus under 10.5 and a warning under 10.6
200 [NSApp finishLaunching];
206 void wxApp::DoCleanUp()
210 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
212 NSRect displayRect = [wxOSXGetMenuScreen() visibleFrame];
213 wxRect r = wxFromNSRect( NULL, displayRect );
219 *width = r.GetWidth();
221 *height = r.GetHeight();
225 void wxGetMousePosition( int* x, int* y )
227 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
234 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
236 wxMouseState wxGetMouseState()
240 wxPoint pt = wxGetMousePosition();
244 NSUInteger modifiers = [NSEvent modifierFlags];
245 NSUInteger buttons = [NSEvent pressedMouseButtons];
247 ms.SetLeftDown( (buttons & 0x01) != 0 );
248 ms.SetMiddleDown( (buttons & 0x04) != 0 );
249 ms.SetRightDown( (buttons & 0x02) != 0 );
251 ms.SetControlDown(modifiers & NSControlKeyMask);
252 ms.SetShiftDown(modifiers & NSShiftKeyMask);
253 ms.SetAltDown(modifiers & NSAlternateKeyMask);
254 ms.SetMetaDown(modifiers & NSCommandKeyMask);
262 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
264 return new wxOSXTimerImpl(timer);
267 int gs_wxBusyCursorCount = 0;
268 extern wxCursor gMacCurrentCursor;
269 wxCursor gMacStoredActiveCursor;
271 // Set the cursor to the busy cursor for all windows
272 void wxBeginBusyCursor(const wxCursor *cursor)
274 if (gs_wxBusyCursorCount++ == 0)
276 gMacStoredActiveCursor = gMacCurrentCursor;
277 cursor->MacInstall();
279 wxSetCursor(*cursor);
281 //else: nothing to do, already set
284 // Restore cursor to normal
285 void wxEndBusyCursor()
287 wxCHECK_RET( gs_wxBusyCursorCount > 0,
288 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
290 if (--gs_wxBusyCursorCount == 0)
292 gMacStoredActiveCursor.MacInstall();
293 gMacStoredActiveCursor = wxNullCursor;
295 wxSetCursor(wxNullCursor);
299 // true if we're between the above two calls
302 return (gs_wxBusyCursorCount > 0);
305 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
307 // wxScreenDC is derived from wxWindowDC, so a screen dc will
308 // call this method when a Blit is performed with it as a source.
312 wxSize sz = m_window->GetSize();
314 int width = subrect != NULL ? subrect->width : sz.x;
315 int height = subrect != NULL ? subrect->height : sz.y ;
317 NSView* view = (NSView*) m_window->GetHandle();
319 // we use this method as other methods force a repaint, and this method can be
320 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
321 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
324 wxBitmap bitmap(width, height);
325 if ( [rep respondsToSelector:@selector(CGImage)] )
327 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
329 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
330 // since our context is upside down we dont use CGContextDrawImage
331 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
332 CGImageRelease(cgImageRef);
337 // TODO for 10.4 in case we can support this for osx_cocoa
346 #endif // wxOSX_USE_COCOA