]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/utils.mm
making sure creation is setup correctly for wx-frame coordinates into cocoa-content...
[wxWidgets.git] / src / osx / cocoa / utils.mm
CommitLineData
33e90275 1/////////////////////////////////////////////////////////////////////////////
0f9b48d1 2// Name: src/osx/cocoa/utils.mm
33e90275
SC
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
33e90275 33 #include <CoreServices/CoreServices.h>
928e7a7e 34 #include "wx/osx/dcclient.h"
33e90275
SC
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
44void wxBell()
45{
46 NSBeep();
47}
48
49// ----------------------------------------------------------------------------
50// Common Event Support
51// ----------------------------------------------------------------------------
52
53void wxMacWakeUp()
54{
3c7eea25
VZ
55 // ensure that we have an auto release pool in place because the event will
56 // be autoreleased from NSEvent:otherEventWithType and we might not have a
57 // global pool during startup or shutdown and we actually never have it if
58 // we're called from another thread
59 //
60 // FIXME: we can't use wxMacAutoreleasePool here because it's in core and
61 // we're in base
62 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
63
64 NSEvent* wakeupEvent = [NSEvent otherEventWithType:NSApplicationDefined
65 location:NSZeroPoint
66 modifierFlags:NSAnyEventMask
67 timestamp:0
68 windowNumber:0
69 context:nil
70 subtype:0
71 data1:0
72 data2:0];
73 [NSApp postEvent:wakeupEvent atStart:NO];
74
75 [pool release];
33e90275
SC
76}
77
78#endif // wxUSE_BASE
945eac79 79
36eca861
SC
80#if wxUSE_GUI
81
c6aa5caf
SC
82@interface wxNSAppController : NSObject
83{
84}
85
86- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
87- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
88- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
89- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
90- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
91- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
92 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
93@end
94
95@implementation wxNSAppController
96
97- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
98{
d8207702 99 wxUnusedVar(sender);
c6aa5caf
SC
100 // let wx do this, not cocoa
101 return NO;
102}
103
104- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
105{
d8207702 106 wxUnusedVar(sender);
c6aa5caf
SC
107 wxCFStringRef cf(wxCFRetain(filename));
108 wxTheApp->MacOpenFile(cf.AsString()) ;
109 return YES;
110}
111
112- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
113{
d8207702 114 wxUnusedVar(sender);
c6aa5caf
SC
115 wxTheApp->MacNewFile() ;
116 return NO;
117}
118
119- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
120{
d8207702 121 wxUnusedVar(sender);
c6aa5caf
SC
122 wxCFStringRef cf(wxCFRetain(filename));
123 wxTheApp->MacPrintFile(cf.AsString()) ;
124 return YES;
125}
126
945eac79 127/*
c6aa5caf
SC
128 Allowable return values are:
129 NSTerminateNow - it is ok to proceed with termination
130 NSTerminateCancel - the application should not be terminated
131 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
132 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
133*/
134- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
135{
d8207702 136 wxUnusedVar(sender);
c6aa5caf
SC
137 wxWindow* win = wxTheApp->GetTopWindow() ;
138 if ( win )
139 {
140 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
945eac79 141 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
c6aa5caf
SC
142 win->Close(true) ;
143 }
144 else
145 {
146 wxTheApp->ExitMainLoop() ;
147 }
148 return NSTerminateCancel;
149}
150
151- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
152{
d8207702
SC
153 wxUnusedVar(flag);
154 wxUnusedVar(sender);
c6aa5caf
SC
155 wxTheApp->MacReopenApp() ;
156 return NO;
157}
158
159- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
160 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
161{
d8207702 162 wxUnusedVar(replyEvent);
c6aa5caf
SC
163 NSString* url = [[event descriptorAtIndex:1] stringValue];
164 wxCFStringRef cf(wxCFRetain(url));
165 wxTheApp->MacOpenURL(cf.AsString()) ;
166}
167@end
168
03647350 169/*
724999ee 170 allows ShowModal to work when using sheets.
03647350 171 see include/wx/osx/cocoa/private.h for more info
724999ee
KO
172*/
173@implementation ModalDialogDelegate
174- (id)init
175{
176 [super init];
177 sheetFinished = NO;
178 resultCode = -1;
179 return self;
180}
181
03647350 182- (BOOL)finished
724999ee
KO
183{
184 return sheetFinished;
185}
186
187- (int)code
188{
189 return resultCode;
190}
191
192- (void)waitForSheetToFinish
193{
194 while (!sheetFinished)
195 {
196 wxSafeYield();
197 }
198}
199
200- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
201{
d8207702 202 wxUnusedVar(contextInfo);
724999ee
KO
203 resultCode = returnCode;
204 sheetFinished = YES;
037f9d3b
KO
205 // NSAlerts don't need nor respond to orderOut
206 if ([sheet respondsToSelector:@selector(orderOut:)])
207 [sheet orderOut: self];
724999ee
KO
208}
209@end
210
dbeddfb9
SC
211bool wxApp::DoInitGui()
212{
ab9df4fb 213 wxMacAutoreleasePool pool;
dbeddfb9 214 [NSApplication sharedApplication];
c6aa5caf
SC
215
216 if (!sm_isEmbedded)
217 {
218 wxNSAppController* controller = [[wxNSAppController alloc] init];
219 [[NSApplication sharedApplication] setDelegate:controller];
945eac79 220
c6aa5caf
SC
221 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
222 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
223 forEventClass:kInternetEventClass andEventID:kAEGetURL];
44ee9ed8 224 [NSApp finishLaunching];
c6aa5caf 225 }
dbeddfb9
SC
226 return true;
227}
228
229void wxApp::DoCleanUp()
230{
231}
33e90275 232
33e90275
SC
233void wxClientDisplayRect(int *x, int *y, int *width, int *height)
234{
235 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
236 wxRect r = wxFromNSRect( NULL, displayRect );
237 if ( x )
238 *x = r.x;
239 if ( y )
240 *y = r.y;
241 if ( width )
242 *width = r.GetWidth();
243 if ( height )
244 *height = r.GetHeight();
945eac79 245
33e90275
SC
246}
247
248void wxGetMousePosition( int* x, int* y )
249{
250 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
54f11060
SC
251 if ( x )
252 *x = pt.x;
253 if ( y )
254 *y = pt.y;
33e90275
SC
255};
256
f3769d53
SC
257#if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
258
259wxMouseState wxGetMouseState()
260{
261 wxMouseState ms;
262
263 wxPoint pt = wxGetMousePosition();
264 ms.SetX(pt.x);
265 ms.SetY(pt.y);
266
267 NSUInteger modifiers = [NSEvent modifierFlags];
268 NSUInteger buttons = [NSEvent pressedMouseButtons];
269
270 ms.SetLeftDown( (buttons & 0x01) != 0 );
271 ms.SetMiddleDown( (buttons & 0x04) != 0 );
272 ms.SetRightDown( (buttons & 0x02) != 0 );
273
274 ms.SetControlDown(modifiers & NSControlKeyMask);
275 ms.SetShiftDown(modifiers & NSShiftKeyMask);
276 ms.SetAltDown(modifiers & NSAlternateKeyMask);
277 ms.SetMetaDown(modifiers & NSCommandKeyMask);
278
279 return ms;
280}
281
282
283#endif
284
33e90275
SC
285wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
286{
dbeddfb9 287 return new wxOSXTimerImpl(timer);
33e90275
SC
288}
289
290int gs_wxBusyCursorCount = 0;
291extern wxCursor gMacCurrentCursor;
292wxCursor gMacStoredActiveCursor;
293
294// Set the cursor to the busy cursor for all windows
295void wxBeginBusyCursor(const wxCursor *cursor)
296{
297 if (gs_wxBusyCursorCount++ == 0)
298 {
299 gMacStoredActiveCursor = gMacCurrentCursor;
300 cursor->MacInstall();
301
302 wxSetCursor(*cursor);
303 }
304 //else: nothing to do, already set
305}
306
307// Restore cursor to normal
308void wxEndBusyCursor()
309{
310 wxCHECK_RET( gs_wxBusyCursorCount > 0,
311 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
312
313 if (--gs_wxBusyCursorCount == 0)
314 {
315 gMacStoredActiveCursor.MacInstall();
316 gMacStoredActiveCursor = wxNullCursor;
317
318 wxSetCursor(wxNullCursor);
319 }
320}
321
322// true if we're between the above two calls
323bool wxIsBusy()
324{
325 return (gs_wxBusyCursorCount > 0);
326}
327
928e7a7e
KO
328wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
329{
330 // wxScreenDC is derived from wxWindowDC, so a screen dc will
331 // call this method when a Blit is performed with it as a source.
332 if (!m_window)
333 return wxNullBitmap;
945eac79 334
928e7a7e 335 wxSize sz = m_window->GetSize();
945eac79 336
928e7a7e
KO
337 int left = subrect != NULL ? subrect->x : 0 ;
338 int top = subrect != NULL ? subrect->y : 0 ;
339 int width = subrect != NULL ? subrect->width : sz.x;
340 int height = subrect != NULL ? subrect->height : sz.y ;
945eac79 341
928e7a7e
KO
342 NSRect rect = NSMakeRect(left, top, width, height );
343 NSView* view = (NSView*) m_window->GetHandle();
344 [view lockFocus];
945eac79 345 // we use this method as other methods force a repaint, and this method can be
928e7a7e
KO
346 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
347 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
348 [view unlockFocus];
03647350 349
1034a6bb
SC
350 wxBitmap bitmap(width, height);
351 if ( [rep respondsToSelector:@selector(CGImage)] )
352 {
353 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
945eac79 354
1034a6bb
SC
355 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
356 // since our context is upside down we dont use CGContextDrawImage
357 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
358 CGImageRelease(cgImageRef);
359 cgImageRef = NULL;
360 }
361 else
362 {
363 // TODO for 10.4 in case we can support this for osx_cocoa
364 }
928e7a7e 365 [rep release];
945eac79 366
928e7a7e
KO
367 return bitmap;
368}
369
33e90275
SC
370#endif // wxUSE_GUI
371
3c7eea25 372#endif // wxOSX_USE_COCOA