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 NSEnumerator *enumerator = [[[NSApplication sharedApplication] windows] objectEnumerator];
279 while ((object = [enumerator nextObject])) {
280 [(NSWindow*) object disableCursorRects];
283 gMacStoredActiveCursor = gMacCurrentCursor;
284 cursor->MacInstall();
286 wxSetCursor(*cursor);
288 //else: nothing to do, already set
291 // Restore cursor to normal
292 void wxEndBusyCursor()
294 wxCHECK_RET( gs_wxBusyCursorCount > 0,
295 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
297 if (--gs_wxBusyCursorCount == 0)
299 NSEnumerator *enumerator = [[[NSApplication sharedApplication] windows] objectEnumerator];
302 while ((object = [enumerator nextObject])) {
303 [(NSWindow*) object enableCursorRects];
306 wxSetCursor(wxNullCursor);
308 gMacStoredActiveCursor.MacInstall();
309 gMacStoredActiveCursor = wxNullCursor;
313 // true if we're between the above two calls
316 return (gs_wxBusyCursorCount > 0);
319 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
321 // wxScreenDC is derived from wxWindowDC, so a screen dc will
322 // call this method when a Blit is performed with it as a source.
326 wxSize sz = m_window->GetSize();
328 int width = subrect != NULL ? subrect->width : sz.x;
329 int height = subrect != NULL ? subrect->height : sz.y ;
331 NSView* view = (NSView*) m_window->GetHandle();
333 // we use this method as other methods force a repaint, and this method can be
334 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
335 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
338 wxBitmap bitmap(width, height);
339 if ( [rep respondsToSelector:@selector(CGImage)] )
341 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
343 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
344 // since our context is upside down we dont use CGContextDrawImage
345 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
346 CGImageRelease(cgImageRef);
351 // TODO for 10.4 in case we can support this for osx_cocoa
360 #endif // wxOSX_USE_COCOA