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"
14 #include "wx/wxprec.h"
22 #include "wx/toplevel.h"
27 #include "wx/apptrait.h"
29 #include "wx/osx/private.h"
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"
49 // ----------------------------------------------------------------------------
50 // Common Event Support
51 // ----------------------------------------------------------------------------
62 @interface wxNSAppController : NSObject
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;
75 @implementation wxNSAppController
77 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
80 // let wx do this, not cocoa
84 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
87 wxCFStringRef cf(wxCFRetain(filename));
88 wxTheApp->MacOpenFile(cf.AsString()) ;
92 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
95 wxTheApp->MacNewFile() ;
99 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
102 wxCFStringRef cf(wxCFRetain(filename));
103 wxTheApp->MacPrintFile(cf.AsString()) ;
108 Allowable return values are:
109 NSTerminateNow - it is ok to proceed with termination
110 NSTerminateCancel - the application should not be terminated
111 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
112 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
114 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
117 wxWindow* win = wxTheApp->GetTopWindow() ;
120 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
121 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
126 wxTheApp->ExitMainLoop() ;
128 return NSTerminateCancel;
131 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
135 wxTheApp->MacReopenApp() ;
139 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
140 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
142 wxUnusedVar(replyEvent);
143 NSString* url = [[event descriptorAtIndex:1] stringValue];
144 wxCFStringRef cf(wxCFRetain(url));
145 wxTheApp->MacOpenURL(cf.AsString()) ;
150 allows ShowModal to work when using sheets.
151 see include/wx/osx/cocoa/private.h for more info
153 @implementation ModalDialogDelegate
164 return sheetFinished;
172 - (void)waitForSheetToFinish
174 while (!sheetFinished)
180 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
182 wxUnusedVar(contextInfo);
183 resultCode = returnCode;
185 // NSAlerts don't need nor respond to orderOut
186 if ([sheet respondsToSelector:@selector(orderOut:)])
187 [sheet orderOut: self];
191 bool wxApp::DoInitGui()
193 wxMacAutoreleasePool pool;
194 [NSApplication sharedApplication];
198 wxNSAppController* controller = [[wxNSAppController alloc] init];
199 [[NSApplication sharedApplication] setDelegate:controller];
201 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
202 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
203 forEventClass:kInternetEventClass andEventID:kAEGetURL];
204 [NSApp finishLaunching];
209 void wxApp::DoCleanUp()
213 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
215 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
216 wxRect r = wxFromNSRect( NULL, displayRect );
222 *width = r.GetWidth();
224 *height = r.GetHeight();
228 void wxGetMousePosition( int* x, int* y )
230 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
237 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
239 return new wxOSXTimerImpl(timer);
242 int gs_wxBusyCursorCount = 0;
243 extern wxCursor gMacCurrentCursor;
244 wxCursor gMacStoredActiveCursor;
246 // Set the cursor to the busy cursor for all windows
247 void wxBeginBusyCursor(const wxCursor *cursor)
249 if (gs_wxBusyCursorCount++ == 0)
251 gMacStoredActiveCursor = gMacCurrentCursor;
252 cursor->MacInstall();
254 wxSetCursor(*cursor);
256 //else: nothing to do, already set
259 // Restore cursor to normal
260 void wxEndBusyCursor()
262 wxCHECK_RET( gs_wxBusyCursorCount > 0,
263 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
265 if (--gs_wxBusyCursorCount == 0)
267 gMacStoredActiveCursor.MacInstall();
268 gMacStoredActiveCursor = wxNullCursor;
270 wxSetCursor(wxNullCursor);
274 // true if we're between the above two calls
277 return (gs_wxBusyCursorCount > 0);
280 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
282 // wxScreenDC is derived from wxWindowDC, so a screen dc will
283 // call this method when a Blit is performed with it as a source.
287 wxSize sz = m_window->GetSize();
289 int left = subrect != NULL ? subrect->x : 0 ;
290 int top = subrect != NULL ? subrect->y : 0 ;
291 int width = subrect != NULL ? subrect->width : sz.x;
292 int height = subrect != NULL ? subrect->height : sz.y ;
294 NSRect rect = NSMakeRect(left, top, width, height );
295 NSView* view = (NSView*) m_window->GetHandle();
297 // we use this method as other methods force a repaint, and this method can be
298 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
299 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
302 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
304 wxBitmap bitmap(CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
305 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
306 // since our context is upside down we dont use CGContextDrawImage
307 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
308 CGImageRelease(cgImageRef);
317 #endif // wxOSX_USE_COCOA