http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / OSX / AppController.m
1 /* xscreensaver, Copyright (c) 2006 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* This is just a test harness, really -- it makes a window with an
13    XScreenSaverGLView in it and a Preferences button, because I don't want
14    to have to debug these programs by installing them as screen savers
15    first!
16  */
17
18 #import "AppController.h"
19 #import "XScreenSaverGLView.h"
20
21 @implementation AppController
22
23 - (ScreenSaverView *) makeSaverView
24 {
25   const char *var = "SCREENSAVER_MODULE";
26   const char *s = getenv (var);
27   if (!s || !*s) {
28     NSAssert1 (0, @"set $%s to the name of the module to run", var);
29     exit(1);
30   }
31   NSString *module = [NSString stringWithCString:s
32                                         encoding:NSUTF8StringEncoding];
33   NSString *dir = [[[NSBundle mainBundle] bundlePath]
34                    stringByDeletingLastPathComponent];
35   NSString *name = [module stringByAppendingPathExtension:@"saver"];
36   NSString *path = [dir stringByAppendingPathComponent:name];
37   NSBundle *bundleToLoad = [NSBundle bundleWithPath:path];
38   Class new_class = [bundleToLoad principalClass];
39   NSAssert1 (new_class, @"unable to load \"%@\"", path);
40
41   NSRect rect;
42   rect.origin.x = rect.origin.y = 0;
43   rect.size.width = 320;
44   rect.size.height = 240;
45
46   id instance = [[new_class alloc] initWithFrame:rect isPreview:YES];
47   NSAssert1 (instance, @"unable to instantiate %@", new_class);
48   return (ScreenSaverView *) instance;
49 }
50
51
52 - (void) openPreferences: (int) which
53 {
54   ScreenSaverView *sv = (which ? saverView1 : saverView0);
55   NSAssert (sv, @"no saver view");
56   NSWindow *prefs = [sv configureSheet];
57
58   [NSApp beginSheet:prefs
59      modalForWindow:[sv window]
60       modalDelegate:self
61      didEndSelector:@selector(preferencesClosed:returnCode:contextInfo:)
62         contextInfo:nil];
63   int code = [NSApp runModalForWindow:prefs];
64   
65   /* Restart the animation if the "OK" button was hit, but not if "Cancel".
66      We have to restart *both* animations, because the xlockmore-style
67      ones will blow up if one re-inits but the other doesn't.
68    */
69   if (code != NSCancelButton) {
70     if (saverView0) [saverView0 stopAnimation];
71     if (saverView1) [saverView1 stopAnimation];
72     if (saverView0) [saverView0 startAnimation];
73     if (saverView1) [saverView1 startAnimation];
74   }
75 }
76
77 - (void) openPreferences0: (NSObject *) button
78 {
79   [self openPreferences:0];
80 }
81
82 - (void) openPreferences1: (NSObject *) button
83 {
84   [self openPreferences:1];
85 }
86
87 - (void) preferencesClosed: (NSWindow *) sheet
88                 returnCode: (int) returnCode
89                contextInfo: (void  *) contextInfo
90 {
91   [NSApp stopModalWithCode:returnCode];
92 }
93
94
95 - (void) makeWindow: (ScreenSaverView *)sv which:(int)which
96 {
97   NSRect rect;
98   
99   if (which)
100     saverView1 = sv;
101   else
102     saverView0 = sv;
103   
104   // make a "Preferences" button
105   //
106   rect.origin.x = rect.origin.y = 0;
107   rect.size.width = rect.size.height = 10;
108   NSButton *pb = [[NSButton alloc] initWithFrame:rect];
109   [pb setTitle:@"Preferences"];
110   [pb setBezelStyle:NSRoundedBezelStyle];
111   [pb sizeToFit];
112   rect.origin.x = ([sv frame].size.width -
113                    [pb frame].size.width) / 2;
114   [pb setFrameOrigin:rect.origin];
115   
116   // grab the click
117   //
118   [pb setTarget:self];
119   if (which)
120     [pb setAction:@selector(openPreferences1:)];
121   else
122     [pb setAction:@selector(openPreferences0:)];
123       
124   // make a box to wrap the saverView
125   //
126   rect = [sv frame];
127   rect.origin.x = 0;
128   rect.origin.y = [pb frame].origin.y + [pb frame].size.height;
129   NSBox *gbox = [[NSBox alloc] initWithFrame:rect];
130   rect.size.width = rect.size.height = 10;
131   [gbox setContentViewMargins:rect.size];
132   [gbox setTitlePosition:NSNoTitle];
133   [gbox addSubview:sv];
134   [gbox sizeToFit];
135
136   // make a box to wrap the other two boxes
137   //
138   rect.origin.x = rect.origin.y = 0;
139   rect.size.width  = [gbox frame].size.width;
140   rect.size.height = [gbox frame].size.height + [gbox frame].origin.y;
141   NSBox *pbox = [[NSBox alloc] initWithFrame:rect];
142   [pbox setTitlePosition:NSNoTitle];
143   [pbox setBorderType:NSNoBorder];
144   [pbox addSubview:gbox];
145   [pbox addSubview:pb];
146   [pbox sizeToFit];
147
148   // and make a window to hold that.
149   //
150   NSScreen *screen = [NSScreen mainScreen];
151   rect = [pbox frame];
152   rect.origin.x = ([screen frame].size.width  - rect.size.width)  / 2;
153   rect.origin.y = ([screen frame].size.height - rect.size.height) / 2;
154   
155   rect.origin.x += rect.size.width * (which ? 0.55 : -0.55);
156   
157   NSWindow *window = [[NSWindow alloc]
158                       initWithContentRect:rect
159                                 styleMask:(NSTitledWindowMask |
160                                            NSClosableWindowMask |
161                                            NSMiniaturizableWindowMask |
162                                            NSResizableWindowMask)
163                                   backing:NSBackingStoreBuffered
164                                     defer:YES
165                                    screen:screen];
166   [window setTitle:@"XScreenSaver"];
167   [window setMinSize:[window frameRectForContentRect:rect].size];
168
169   [[window contentView] addSubview:pbox];
170
171   [sv setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
172   [pb setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin];
173   [gbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
174   [pbox setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
175     
176   [window setFrameAutosaveName:(which
177                                 ? @"SaverDebugWindow1"
178                                 : @"SaverDebugWindow0")];
179   [window setFrameUsingName:[window frameAutosaveName]];
180   
181   [window makeKeyAndOrderFront:window];
182   
183   [sv startAnimation];
184 }
185
186
187 - (void)applicationDidFinishLaunching: (NSNotification *) n
188 {
189   [self makeWindow:[self makeSaverView] which:0];
190   [self makeWindow:[self makeSaverView] which:1];
191 }
192
193 /* When the window closes, exit (even if prefs still open.)
194 */
195 - (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *) n
196 {
197   return YES;
198 }
199
200 @end