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 @interface wxNSAppController : NSObject wxOSX_10_6_AND_LATER(<NSApplicationDelegate>)
56 - (void)applicationWillFinishLaunching:(NSApplication *)sender;
58 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
59 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
60 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
61 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
62 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
64 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
65 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
66 - (void)applicationWillTerminate:(NSApplication *)sender;
69 @implementation wxNSAppController
71 - (void)applicationWillFinishLaunching:(NSApplication *)application {
72 wxUnusedVar(application);
75 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
78 wxCFStringRef cf(wxCFRetain(filename));
79 wxTheApp->MacOpenFile(cf.AsString()) ;
83 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
86 wxTheApp->MacNewFile() ;
90 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
93 wxCFStringRef cf(wxCFRetain(filename));
94 wxTheApp->MacPrintFile(cf.AsString()) ;
98 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
102 wxTheApp->MacReopenApp() ;
106 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
107 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
109 wxUnusedVar(replyEvent);
110 NSString* url = [[event descriptorAtIndex:1] stringValue];
111 wxCFStringRef cf(wxCFRetain(url));
112 wxTheApp->MacOpenURL(cf.AsString()) ;
116 Allowable return values are:
117 NSTerminateNow - it is ok to proceed with termination
118 NSTerminateCancel - the application should not be terminated
119 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
120 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
122 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
126 wxTheApp->OnQueryEndSession(event);
127 if ( event.GetVeto() )
128 return NSTerminateCancel;
130 return NSTerminateNow;
133 - (void)applicationWillTerminate:(NSApplication *)application {
134 wxUnusedVar(application);
136 event.SetCanVeto(false);
137 wxTheApp->OnEndSession(event);
140 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
143 // let wx do this, not cocoa
150 allows ShowModal to work when using sheets.
151 see include/wx/osx/cocoa/private.h for more info
153 @implementation ModalDialogDelegate
163 - (void)setImplementation: (wxDialog *)dialog
170 return sheetFinished;
178 - (void)waitForSheetToFinish
180 while (!sheetFinished)
186 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
188 wxUnusedVar(contextInfo);
189 resultCode = returnCode;
191 // NSAlerts don't need nor respond to orderOut
192 if ([sheet respondsToSelector:@selector(orderOut:)])
193 [sheet orderOut: self];
196 impl->ModalFinishedCallback(sheet, returnCode);
200 bool wxApp::DoInitGui()
202 wxMacAutoreleasePool pool;
203 [NSApplication sharedApplication];
207 wxNSAppController* controller = [[wxNSAppController alloc] init];
208 [NSApp setDelegate:controller];
210 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
211 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
212 forEventClass:kInternetEventClass andEventID:kAEGetURL];
214 [NSApp finishLaunching];
219 void wxApp::DoCleanUp()
223 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
225 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
226 wxRect r = wxFromNSRect( NULL, displayRect );
232 *width = r.GetWidth();
234 *height = r.GetHeight();
238 void wxGetMousePosition( int* x, int* y )
240 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
247 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
249 wxMouseState wxGetMouseState()
253 wxPoint pt = wxGetMousePosition();
257 NSUInteger modifiers = [NSEvent modifierFlags];
258 NSUInteger buttons = [NSEvent pressedMouseButtons];
260 ms.SetLeftDown( (buttons & 0x01) != 0 );
261 ms.SetMiddleDown( (buttons & 0x04) != 0 );
262 ms.SetRightDown( (buttons & 0x02) != 0 );
264 ms.SetControlDown(modifiers & NSControlKeyMask);
265 ms.SetShiftDown(modifiers & NSShiftKeyMask);
266 ms.SetAltDown(modifiers & NSAlternateKeyMask);
267 ms.SetMetaDown(modifiers & NSCommandKeyMask);
275 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
277 return new wxOSXTimerImpl(timer);
280 int gs_wxBusyCursorCount = 0;
281 extern wxCursor gMacCurrentCursor;
282 wxCursor gMacStoredActiveCursor;
284 // Set the cursor to the busy cursor for all windows
285 void wxBeginBusyCursor(const wxCursor *cursor)
287 if (gs_wxBusyCursorCount++ == 0)
289 gMacStoredActiveCursor = gMacCurrentCursor;
290 cursor->MacInstall();
292 wxSetCursor(*cursor);
294 //else: nothing to do, already set
297 // Restore cursor to normal
298 void wxEndBusyCursor()
300 wxCHECK_RET( gs_wxBusyCursorCount > 0,
301 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
303 if (--gs_wxBusyCursorCount == 0)
305 gMacStoredActiveCursor.MacInstall();
306 gMacStoredActiveCursor = wxNullCursor;
308 wxSetCursor(wxNullCursor);
312 // true if we're between the above two calls
315 return (gs_wxBusyCursorCount > 0);
318 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
320 // wxScreenDC is derived from wxWindowDC, so a screen dc will
321 // call this method when a Blit is performed with it as a source.
325 wxSize sz = m_window->GetSize();
327 int left = subrect != NULL ? subrect->x : 0 ;
328 int top = subrect != NULL ? subrect->y : 0 ;
329 int width = subrect != NULL ? subrect->width : sz.x;
330 int height = subrect != NULL ? subrect->height : sz.y ;
332 NSRect rect = NSMakeRect(left, top, width, height );
333 NSView* view = (NSView*) m_window->GetHandle();
335 // we use this method as other methods force a repaint, and this method can be
336 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
337 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
340 wxBitmap bitmap(width, height);
341 if ( [rep respondsToSelector:@selector(CGImage)] )
343 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
345 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
346 // since our context is upside down we dont use CGContextDrawImage
347 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
348 CGImageRelease(cgImageRef);
353 // TODO for 10.4 in case we can support this for osx_cocoa
362 #endif // wxOSX_USE_COCOA