ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/Controller.mm
Revision: 1.7
Committed: 2003-03-11T11:31:01Z (21 years, 8 months ago) by nigel
Branch: MAIN
CVS Tags: nigel-build-12
Changes since 1.6: +11 -5 lines
Log Message:
Simplified (and sped up) mouse movement processing when in fullscreen mode.

File Contents

# Content
1 /*
2 * Controller.m - Simple application window management.
3 *
4 * $Id: Controller.mm,v 1.6 2003/01/10 23:01:48 nigel Exp $
5 *
6 * Basilisk II (C) 1997-2001 Christian Bauer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #import "Controller.h"
24 #import "Emulator.h"
25
26 @implementation Controller
27
28 #import "sysdeps.h" // Types used in Basilisk C++ code
29
30 #import <main.h>
31 #import <prefs.h>
32
33 #define DEBUG 0
34 #import <debug.h>
35
36 #import "misc_macosx.h"
37 #import "video_macosx.h"
38
39 //
40 // Standard NSApplication methods that we override
41 //
42
43 - (id) init
44 {
45 #ifdef ENABLE_MULTIPLE
46 emulators = [NSMutableArray new];
47 #endif
48 return [super init];
49 }
50
51 - (void) dealloc
52 {
53 #ifdef ENABLE_MULTIPLE
54 [emulators dealloc];
55 #endif
56 [super dealloc];
57 }
58
59 - (void) awakeFromNib
60 {
61 #ifdef ENABLE_MULTIPLE
62 [self NewEmulator: self]; // So the user gets something on screen
63 #endif
64 [[NSApplication sharedApplication]
65 setDelegate: self]; // Enable applicationShouldTerminate
66 }
67
68 - (void) sendEvent: (NSEvent *)event;
69 {
70 if ( [self isAnyEmulatorDisplayingSheets] || ! [self isAnyEmulatorRunning] )
71 [super sendEvent: event];
72 else
73 {
74 NSEventType type = [event type];
75
76 if ( type == NSKeyUp || type == NSKeyDown || type == NSFlagsChanged )
77 [self dispatchKeyEvent: event
78 type: type];
79 else
80 [self dispatchEvent: event
81 type: type];
82 }
83 }
84
85 // NSApplication methods which are invoked through delegation
86
87 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)app
88 { return YES; }
89
90 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *)app
91 {
92 short count;
93 char *stillRunningMessage;
94
95 if ( [thePrefsEditor hasEdited] )
96 if ( ChoiceAlert("Preferences have been edited",
97 "Save changes", "Quit") )
98 SavePrefs();
99
100 // if ( edited )
101 // {
102 // NSString *title = [NSString stringWithCString: getString(STR_WARNING_ALERT_TITLE)],
103 // *msg = @"Preferences have been edited",
104 // *def = @"Save changes",
105 // *alt = @"Quit Application",
106 // *other = @"Continue";
107 //
108 // switch ( NSRunAlertPanel(title, msg, def, alt, other, nil) )
109 // {
110 // case NSAlertDefault: savePrefs();
111 // case NSAlertAlternate: return NSTerminateNow;
112 // case NSAlertOther: return NSTerminateCancel;
113 // }
114 // }
115
116
117 if ( [[thePrefsEditor window] isVisible] )
118 [[thePrefsEditor window] performClose: self];
119
120
121 count = [self emulatorCreatedCount];
122
123 if ( count > 0 )
124 {
125 if ( count > 1 )
126 stillRunningMessage = "Emulators are still running\nExiting Basilisk may lose data";
127 else
128 stillRunningMessage = "Emulator is still running\nExiting Basilisk may lose data";
129 if ( ! ChoiceAlert(stillRunningMessage, "Exit", "Continue") )
130 return NSTerminateCancel; // NSTerminateLater?
131 }
132
133 return NSTerminateNow;
134 }
135
136
137 // Event dispatching, called by sendEvent
138
139 - (void) dispatchKeyEvent: (NSEvent *)event
140 type: (NSEventType)type
141 {
142 EmulatorView *view;
143
144 #ifdef ENABLE_MULTIPLE
145 // We need to work out what window's Emulator should receive these messages
146
147
148 int tmp;
149
150 for ( tmp = 0; tmp < [emulators count], ++tmp )
151 {
152 theEmulator = [emulators objectAtIndex: tmp];
153 view = [theEmulator screen];
154
155 if ( [ theEmulator isRunning ] &&
156 ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
157 break;
158 }
159
160 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
161 #else
162 view = [theEmulator screen];
163
164 if ( [theEmulator isRunning] &&
165 ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
166 #endif
167 {
168 D(NSLog(@"Got a key event - %d\n", [event keyCode]));
169 switch ( type )
170 {
171 case NSKeyUp:
172 [view keyUp: event];
173 break;
174 case NSKeyDown:
175 D(NSLog(@"%s - NSKeyDown - %@", __PRETTY_FUNCTION__, event));
176 [view keyDown: event];
177 break;
178 case NSFlagsChanged:
179 [view flagsChanged: event];
180 break;
181 default:
182 NSLog(@"%s - Sent a non-key event (logic error)",
183 __PRETTY_FUNCTION__);
184 [super sendEvent: event];
185 }
186 }
187 else // No Basilisk window is key (maybe a panel or pane).
188 [super sendEvent: event]; // Call NSApplication default
189
190 }
191
192 - (void) dispatchEvent: (NSEvent *)event
193 type: (NSEventType)type
194 {
195 EmulatorView *view;
196 BOOL fullScreen;
197
198 #ifdef ENABLE_MULTIPLE
199 // We need to work out what window's Emulator should receive these messages
200
201
202 int tmp;
203
204 for ( tmp = 0; tmp < [emulators count], ++tmp )
205 {
206 theEmulator = [emulators objectAtIndex: tmp];
207 view = [theEmulator screen];
208 fullScreen = [view isFullScreen];
209
210 if ( [theEmulator isRunning] &&
211 ( fullScreen || [[theEmulator window] isMainWindow] ) )
212 break;
213 }
214
215 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
216 #else
217 view = [theEmulator screen];
218 fullScreen = [view isFullScreen];
219
220 if ( [theEmulator isRunning] &&
221 ( fullScreen || [[theEmulator window] isMainWindow] ) )
222 #endif
223 {
224 if ( fullScreen || [view mouseInView: event] )
225 {
226 switch ( type )
227 {
228 case NSLeftMouseDown:
229 [view mouseDown: event];
230 break;
231 case NSLeftMouseUp:
232 [view mouseUp: event];
233 break;
234 case NSLeftMouseDragged:
235 case NSMouseMoved:
236 if ( fullScreen )
237 [view fullscreenMouseMove];
238 else
239 [view processMouseMove: event];
240 break;
241 default:
242 [super sendEvent: event]; // NSApplication default
243 }
244 return;
245 }
246 }
247
248 // Either the pointer is not in the Emulator's screen, no Basilisk window is running,
249 // or no Basilisk window is main (e.g. there might be a panel or pane up).
250 //
251 // We should just be calling NSApp's default sendEvent, but then for some reason
252 // mouseMoved events are still passed to our EmulatorView, so we filter them out.
253
254 if ( type != NSMouseMoved )
255 [super sendEvent: event];
256 }
257
258
259 // Methods to display documentation:
260
261 - (IBAction) HelpToDo: (id)sender
262 {
263 NSString *path = [[NSBundle mainBundle] pathForResource: @"ToDo"
264 ofType: @"html"];
265
266 if ( ! path )
267 InfoSheet(@"Cannot find ToDo.html", [theEmulator window]);
268 else
269 if ( ! [[NSWorkspace sharedWorkspace] openFile: path
270 withApplication: @"TextEdit"] )
271 InfoSheet(@"Cannot open ToDo.html with TextEdit", [theEmulator window]);
272 }
273
274 - (IBAction) HelpVersions: (id)sender
275 {
276 NSString *path = [[NSBundle mainBundle] pathForResource: @"Versions"
277 ofType: @"html"];
278
279 if ( ! path )
280 InfoSheet(@"Cannot find Versions.html", [theEmulator window]);
281 else
282 if ( ! [[NSWorkspace sharedWorkspace] openFile: path
283 withApplication: @"TextEdit"] )
284 InfoSheet(@"Cannot open Versions.html with TextEdit", [theEmulator window]);
285 }
286
287
288 // Menu items which for managing more than one window
289
290 #ifdef ENABLE_MULTIPLE
291
292 - (IBAction) NewEmulator: (id)sender
293 {
294 NSString *title;
295
296 if ( ! [NSBundle loadNibNamed:@"Win512x342" owner:self] )
297 {
298 NSLog(@"%s - LoadNibNamed@Win512x342 failed", __PRETTY_FUNCTION__);
299 return;
300 }
301
302 if ( theEmulator == nil)
303 {
304 NSLog(@"%s - Newly created emulator's NIB stuff not fully linked?", __PRETTY_FUNCTION__);
305 return;
306 }
307
308 [emulators addObject: theEmulator];
309 title = [NSString localizedStringWithFormat:@"BasiliskII Emulator %d", [emulators count]];
310 [theEmulator -> win setTitle: title];
311 }
312
313 - (IBAction) PauseAll: (id)sender
314 {
315 [emulators makeObjectsPerformSelector:@selector(Suspend:)
316 withObject:self];
317 }
318
319 - (IBAction) RunAll: (id)sender
320 {
321 [emulators makeObjectsPerformSelector:@selector(Resume:)
322 withObject:self];
323 }
324
325 - (IBAction) TerminateAll: (id)sender
326 {
327 [emulators makeObjectsPerformSelector:@selector(Terminate:)
328 withObject:self];
329 }
330
331 #endif
332
333 - (BOOL) isAnyEmulatorDisplayingSheets
334 {
335 #ifdef ENABLE_MULTIPLE
336 int tmp;
337
338 for ( tmp = 0; tmp < [emulators count], ++tmp )
339 if ( [[[emulators objectAtIndex: tmp] window] attachedSheet] )
340 break;
341
342 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
343 #else
344 if ( [[theEmulator window] attachedSheet] )
345 #endif
346 return TRUE;
347
348 return FALSE;
349 }
350
351 - (BOOL) isAnyEmulatorRunning
352 {
353 #ifdef ENABLE_MULTIPLE
354 int tmp;
355
356 for ( tmp = 0; tmp < [emulators count], ++tmp )
357 if ( [[emulators objectAtIndex: tmp] isRunning] )
358 break;
359
360 if ( tmp < [emulators count] ) // i.e. if we exited the for loop
361 #else
362 if ( [theEmulator isRunning] )
363 #endif
364 return TRUE;
365
366 return FALSE;
367 }
368
369 - (short) emulatorCreatedCount
370 {
371 short count = 0;
372 #ifdef ENABLE_MULTIPLE
373 int tmp;
374
375 for ( tmp = 0; tmp < [emulators count], ++tmp )
376 if ( [[emulators objectAtIndex: tmp] uaeCreated] )
377 ++count;
378 #else
379 if ( [theEmulator uaeCreated] )
380 ++count;
381 #endif
382
383 return count;
384 }
385
386 @end