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

# User Rev Content
1 nigel 1.2 /*
2     * Controller.m - Simple application window management.
3     *
4 nigel 1.7 * $Id: Controller.mm,v 1.6 2003/01/10 23:01:48 nigel Exp $
5 nigel 1.2 *
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 nigel 1.6 #import "misc_macosx.h"
37 nigel 1.2 #import "video_macosx.h"
38    
39     //
40     // Standard NSApplication methods that we override
41     //
42    
43     - (id) init
44     {
45     #ifdef ENABLE_MULTIPLE
46 nigel 1.5 emulators = [NSMutableArray new];
47 nigel 1.2 #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 nigel 1.4 if ( [self isAnyEmulatorDisplayingSheets] || ! [self isAnyEmulatorRunning] )
71     [super sendEvent: event];
72     else
73     {
74     NSEventType type = [event type];
75 nigel 1.2
76 nigel 1.4 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 nigel 1.2 }
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 nigel 1.4 view = [theEmulator screen];
154    
155     if ( [ theEmulator isRunning ] &&
156     ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
157 nigel 1.2 break;
158     }
159    
160     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
161     #else
162 nigel 1.4 view = [theEmulator screen];
163    
164     if ( [theEmulator isRunning] &&
165     ( [[theEmulator window] isKeyWindow] || [view isFullScreen] ) )
166 nigel 1.2 #endif
167     {
168 nigel 1.4 D(NSLog(@"Got a key event - %d\n", [event keyCode]));
169 nigel 1.2 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 nigel 1.4 EmulatorView *view;
196 nigel 1.7 BOOL fullScreen;
197 nigel 1.4
198 nigel 1.2 #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 nigel 1.4 view = [theEmulator screen];
208 nigel 1.7 fullScreen = [view isFullScreen];
209 nigel 1.4
210     if ( [theEmulator isRunning] &&
211 nigel 1.7 ( fullScreen || [[theEmulator window] isMainWindow] ) )
212 nigel 1.2 break;
213     }
214    
215     if ( tmp < [emulators count] ) // i.e. if we exited the for loop
216     #else
217 nigel 1.4 view = [theEmulator screen];
218 nigel 1.7 fullScreen = [view isFullScreen];
219 nigel 1.4
220     if ( [theEmulator isRunning] &&
221 nigel 1.7 ( fullScreen || [[theEmulator window] isMainWindow] ) )
222 nigel 1.2 #endif
223     {
224 nigel 1.7 if ( fullScreen || [view mouseInView: event] )
225 nigel 1.2 {
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 nigel 1.7 if ( fullScreen )
237     [view fullscreenMouseMove];
238     else
239     [view processMouseMove: event];
240 nigel 1.2 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 nigel 1.6
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 nigel 1.2
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 nigel 1.4
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 nigel 1.2
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