]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/utils.mm
Fixed bug: wxPropertyGridInterface::SetPropertyReadOnly() with wxPG_DONT_RECURSE...
[wxWidgets.git] / src / osx / cocoa / utils.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/utils.mm
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
33 #include <CoreServices/CoreServices.h>
34 #include "wx/osx/dcclient.h"
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
44 void wxBell()
45 {
46 NSBeep();
47 }
48
49 // ----------------------------------------------------------------------------
50 // Common Event Support
51 // ----------------------------------------------------------------------------
52
53 void wxMacWakeUp()
54 {
55 // TODO
56 }
57
58 #endif // wxUSE_BASE
59
60 #if wxUSE_GUI
61
62 @interface wxNSAppController : NSObject
63 {
64 }
65
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;
73 @end
74
75 @implementation wxNSAppController
76
77 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
78 {
79 wxUnusedVar(sender);
80 // let wx do this, not cocoa
81 return NO;
82 }
83
84 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
85 {
86 wxUnusedVar(sender);
87 wxCFStringRef cf(wxCFRetain(filename));
88 wxTheApp->MacOpenFile(cf.AsString()) ;
89 return YES;
90 }
91
92 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
93 {
94 wxUnusedVar(sender);
95 wxTheApp->MacNewFile() ;
96 return NO;
97 }
98
99 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
100 {
101 wxUnusedVar(sender);
102 wxCFStringRef cf(wxCFRetain(filename));
103 wxTheApp->MacPrintFile(cf.AsString()) ;
104 return YES;
105 }
106
107 /*
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.
113 */
114 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
115 {
116 wxUnusedVar(sender);
117 wxWindow* win = wxTheApp->GetTopWindow() ;
118 if ( win )
119 {
120 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
121 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
122 win->Close(true) ;
123 }
124 else
125 {
126 wxTheApp->ExitMainLoop() ;
127 }
128 return NSTerminateCancel;
129 }
130
131 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
132 {
133 wxUnusedVar(flag);
134 wxUnusedVar(sender);
135 wxTheApp->MacReopenApp() ;
136 return NO;
137 }
138
139 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
140 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
141 {
142 wxUnusedVar(replyEvent);
143 NSString* url = [[event descriptorAtIndex:1] stringValue];
144 wxCFStringRef cf(wxCFRetain(url));
145 wxTheApp->MacOpenURL(cf.AsString()) ;
146 }
147 @end
148
149 /*
150 allows ShowModal to work when using sheets.
151 see include/wx/osx/cocoa/private.h for more info
152 */
153 @implementation ModalDialogDelegate
154 - (id)init
155 {
156 [super init];
157 sheetFinished = NO;
158 resultCode = -1;
159 return self;
160 }
161
162 - (BOOL)finished
163 {
164 return sheetFinished;
165 }
166
167 - (int)code
168 {
169 return resultCode;
170 }
171
172 - (void)waitForSheetToFinish
173 {
174 while (!sheetFinished)
175 {
176 wxSafeYield();
177 }
178 }
179
180 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
181 {
182 wxUnusedVar(contextInfo);
183 resultCode = returnCode;
184 sheetFinished = YES;
185 // NSAlerts don't need nor respond to orderOut
186 if ([sheet respondsToSelector:@selector(orderOut:)])
187 [sheet orderOut: self];
188 }
189 @end
190
191 bool wxApp::DoInitGui()
192 {
193 wxMacAutoreleasePool pool;
194 [NSApplication sharedApplication];
195
196 if (!sm_isEmbedded)
197 {
198 wxNSAppController* controller = [[wxNSAppController alloc] init];
199 [[NSApplication sharedApplication] setDelegate:controller];
200
201 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
202 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
203 forEventClass:kInternetEventClass andEventID:kAEGetURL];
204 [NSApp finishLaunching];
205 }
206 return true;
207 }
208
209 void wxApp::DoCleanUp()
210 {
211 }
212
213 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
214 {
215 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
216 wxRect r = wxFromNSRect( NULL, displayRect );
217 if ( x )
218 *x = r.x;
219 if ( y )
220 *y = r.y;
221 if ( width )
222 *width = r.GetWidth();
223 if ( height )
224 *height = r.GetHeight();
225
226 }
227
228 void wxGetMousePosition( int* x, int* y )
229 {
230 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
231 if ( x )
232 *x = pt.x;
233 if ( y )
234 *y = pt.y;
235 };
236
237 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
238 {
239 return new wxOSXTimerImpl(timer);
240 }
241
242 int gs_wxBusyCursorCount = 0;
243 extern wxCursor gMacCurrentCursor;
244 wxCursor gMacStoredActiveCursor;
245
246 // Set the cursor to the busy cursor for all windows
247 void wxBeginBusyCursor(const wxCursor *cursor)
248 {
249 if (gs_wxBusyCursorCount++ == 0)
250 {
251 gMacStoredActiveCursor = gMacCurrentCursor;
252 cursor->MacInstall();
253
254 wxSetCursor(*cursor);
255 }
256 //else: nothing to do, already set
257 }
258
259 // Restore cursor to normal
260 void wxEndBusyCursor()
261 {
262 wxCHECK_RET( gs_wxBusyCursorCount > 0,
263 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
264
265 if (--gs_wxBusyCursorCount == 0)
266 {
267 gMacStoredActiveCursor.MacInstall();
268 gMacStoredActiveCursor = wxNullCursor;
269
270 wxSetCursor(wxNullCursor);
271 }
272 }
273
274 // true if we're between the above two calls
275 bool wxIsBusy()
276 {
277 return (gs_wxBusyCursorCount > 0);
278 }
279
280 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
281 {
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.
284 if (!m_window)
285 return wxNullBitmap;
286
287 wxSize sz = m_window->GetSize();
288
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 ;
293
294 NSRect rect = NSMakeRect(left, top, width, height );
295 NSView* view = (NSView*) m_window->GetHandle();
296 [view lockFocus];
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];
300 [view unlockFocus];
301
302 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
303
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);
309 cgImageRef = NULL;
310 [rep release];
311
312 return bitmap;
313 }
314
315 #endif // wxUSE_GUI
316
317 #endif // wxOSX_USE_COCOA