]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/utils.mm
Start on Get/SetStyle support for OS X Cocoa wxTextCtrl.
[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
257wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
258{
dbeddfb9 259 return new wxOSXTimerImpl(timer);
33e90275
SC
260}
261
262int gs_wxBusyCursorCount = 0;
263extern wxCursor gMacCurrentCursor;
264wxCursor gMacStoredActiveCursor;
265
266// Set the cursor to the busy cursor for all windows
267void wxBeginBusyCursor(const wxCursor *cursor)
268{
269 if (gs_wxBusyCursorCount++ == 0)
270 {
271 gMacStoredActiveCursor = gMacCurrentCursor;
272 cursor->MacInstall();
273
274 wxSetCursor(*cursor);
275 }
276 //else: nothing to do, already set
277}
278
279// Restore cursor to normal
280void wxEndBusyCursor()
281{
282 wxCHECK_RET( gs_wxBusyCursorCount > 0,
283 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
284
285 if (--gs_wxBusyCursorCount == 0)
286 {
287 gMacStoredActiveCursor.MacInstall();
288 gMacStoredActiveCursor = wxNullCursor;
289
290 wxSetCursor(wxNullCursor);
291 }
292}
293
294// true if we're between the above two calls
295bool wxIsBusy()
296{
297 return (gs_wxBusyCursorCount > 0);
298}
299
928e7a7e
KO
300wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
301{
302 // wxScreenDC is derived from wxWindowDC, so a screen dc will
303 // call this method when a Blit is performed with it as a source.
304 if (!m_window)
305 return wxNullBitmap;
945eac79 306
928e7a7e 307 wxSize sz = m_window->GetSize();
945eac79 308
928e7a7e
KO
309 int left = subrect != NULL ? subrect->x : 0 ;
310 int top = subrect != NULL ? subrect->y : 0 ;
311 int width = subrect != NULL ? subrect->width : sz.x;
312 int height = subrect != NULL ? subrect->height : sz.y ;
945eac79 313
928e7a7e
KO
314 NSRect rect = NSMakeRect(left, top, width, height );
315 NSView* view = (NSView*) m_window->GetHandle();
316 [view lockFocus];
945eac79 317 // we use this method as other methods force a repaint, and this method can be
928e7a7e
KO
318 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
319 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
320 [view unlockFocus];
03647350 321
1034a6bb
SC
322 wxBitmap bitmap(width, height);
323 if ( [rep respondsToSelector:@selector(CGImage)] )
324 {
325 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
945eac79 326
1034a6bb
SC
327 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
328 // since our context is upside down we dont use CGContextDrawImage
329 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
330 CGImageRelease(cgImageRef);
331 cgImageRef = NULL;
332 }
333 else
334 {
335 // TODO for 10.4 in case we can support this for osx_cocoa
336 }
928e7a7e 337 [rep release];
945eac79 338
928e7a7e
KO
339 return bitmap;
340}
341
33e90275
SC
342#endif // wxUSE_GUI
343
3c7eea25 344#endif // wxOSX_USE_COCOA