]> git.saurik.com Git - apple/boot.git/blame - i386/boot2/old/browser.c
boot-80.1.tar.gz
[apple/boot.git] / i386 / boot2 / old / browser.c
CommitLineData
14c7c974
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
27 */
28
29#import "libsa.h"
30#import "console.h"
31#import "fontio.h"
32#import "graphics.h"
33#import "button.h"
34#import "browser.h"
35#import "scrollbar.h"
36#import "ns_logo.h"
37#import "dot.h"
38#import "hdot.h"
39#import "keys.h"
40
41#define max(a,b) ((a) > (b) ? (a) : (b))
42#define min(a,b) ((a) < (b) ? (a) : (b))
43
44browser_t *
45createBrowser(
46 char **items,
47 int nitems,
48 char *top_message,
49 char *bottom_message,
50 char *button_string,
51 int type
52)
53{
54 browser_t *bp;
55 register int i;
56
57 bp = (browser_t *)zalloc(sizeof(browser_t));
58 bp->items = items;
59 bp->nitems = nitems;
60 bp->bot_visible = min( MAX_ITEMS_VISIBLE - 1, nitems - 1 );
61 /* bp->top_visible = 0; */
62
63 bp->top_message = top_message;
64 bp->top_h = max (strheight(bp->top_message), ns_logo_bitmap_HEIGHT);
65 bp->top_w = strwidth(bp->top_message) + ns_logo_bitmap_WIDTH +
66 BROWSER_XMARGIN;
67 bp->bottom_message = bottom_message;
68 bp->bottom_h = bottom_message ?
69 strheight(bottom_message) :
70 -BROWSER_YMARGIN;
71 bp->bottom_w = strwidth(bottom_message);
72 if (nitems) {
73 bp->selected = (char *)zalloc(nitems);
74 if (type == BROWSER_CURRENT_IS_SELECTED)
75 bp->selected[0] = 1;
76 bp->item_h = strheight(items[0]);
77 for(i=0; i < nitems; i++)
78 bp->item_w = max(bp->item_w, strwidth(items[i]));
79 bp->item_w += 2 * BROWSER_XMARGIN + dot_bitmap_WIDTH;
80 bp->item_box_w = bp->item_w + 2 * BROWSER_XMARGIN;
81 bp->item_box_h = bp->item_h * (bp->bot_visible - bp->top_visible + 1)
82 + 2 * BROWSER_YMARGIN;
83 initScrollbar(&bp->scrollbar, 0, 0, SB_WIDTH,
84 bp->item_box_h - 2 * POPUP_FRAME_MARGIN,
85 0, (bp->bot_visible - bp->top_visible + 1) * 100 / bp->nitems);
86 bp->item_box_w += SB_WIDTH + POPUP_FRAME_MARGIN;
87 } else {
88 bp->item_box_h = -BROWSER_YMARGIN;
89 }
90 initButton(&bp->button, 0, 0, button_string, BUTTON_DRAW_RETURN);
91 bp->h = bp->top_h + bp->item_box_h + bp->bottom_h +
92 bp->button.loc.h + 5 * BROWSER_YMARGIN;
93 bp->w = max(bp->top_w, bp->bottom_w);
94 bp->w = max(bp->w, bp->item_box_w) + 2 * BROWSER_XMARGIN;
95 bp->x = (SCREEN_W - bp->w) / 2;
96 bp->y = (SCREEN_H - bp->h) / 2;
97 if (nitems) {
98 bp->item_box_x = bp->x + (bp->w - bp->item_box_w) / 2;
99 bp->scrollbar.loc.x = bp->item_box_x + POPUP_FRAME_MARGIN;
100 bp->item_box_y = bp->y + 2 * BROWSER_YMARGIN + bp->top_h;
101 bp->scrollbar.loc.y = bp->item_box_y + POPUP_FRAME_MARGIN;
102 }
103 bp->bottom_y = bp->y + 3 * BROWSER_YMARGIN + bp->top_h + bp->item_box_h;
104 bp->button.loc.x = bp->x + bp->w - bp->button.loc.w - BROWSER_XMARGIN;
105 bp->button.loc.y = bp->y + bp->h - bp->button.loc.h - BROWSER_YMARGIN;
106
107 bp->type = type;
108
109 return bp;
110}
111
112inline void
113destroyBrowser(
114 browser_t *bp
115)
116{
117/* destroyButton(bp->button); */
118/* destroyScrollbar(bp->scrollbar); */
119 zfree((char *)bp);
120}
121
122static int item_y(
123 browser_t *bp,
124 int item_num
125)
126{
127 return ((bp)->item_box_y + BROWSER_YMARGIN +
128 (item_num - bp->top_visible) * (bp)->item_h + (bp)->item_h / 2);
129}
130
131setItemHighlight(browser_t *bp, int item, int highlight)
132{
133 register int xpos = bp->item_box_x + POPUP_FRAME_MARGIN +
134 SB_WIDTH + BROWSER_XMARGIN;
135 if (currentMode() != GRAPHICS_MODE ||
136 item < bp->top_visible ||
137 item > bp->bot_visible)
138 return;
139 blit_clear(bp->item_w, xpos, item_y(bp, item),
140 CENTER_V, highlight ? COLOR_WHITE : TEXT_BG);
141 if (bp->selected[item])
142 copyImage( highlight ? &hdot_bitmap : &dot_bitmap,
143 xpos,
144 item_y(bp, item) - dot_bitmap_HEIGHT/2);
145 xpos += BROWSER_XMARGIN + dot_bitmap_WIDTH;
146 blit_string(bp->items[item], xpos, item_y(bp, item),
147 TEXT_FG, CENTER_V);
148}
149
150static void drawItembox(browser_t *bp)
151{
152 register int i;
153 bp->scrollbar.position = bp->top_visible * 100 / bp->nitems;
154 drawScrollbar(&bp->scrollbar);
155 for(i = bp->top_visible; i <= bp->bot_visible; i++)
156 setItemHighlight(bp, i, i == bp->current);
157}
158
159static char *Separator = "----------------------------------------\n";
160
161void drawBrowser(browser_t *bp)
162{
163 short item_y;
164 register int i;
165
166 clearActivityIndicator();
167 if (currentMode() == TEXT_MODE) {
168 printf("%s", Separator);
169 if (bp->top_message) {
170 printf("%s\n%s",bp->top_message, Separator);
171 }
172 if (bp->nitems) {
173 for (i = bp->top_visible; i <= bp->bot_visible; i++) {
174 printf("% 2d. %c %s\n",i+1,
175 bp->selected[i] ? '*' : ' ',
176 bp->items[i]);
177 }
178 if (bp->bot_visible != bp->nitems - 1)
179 printf("......<More>\n");
180 printf(Separator);
181 }
182 if (bp->bottom_message) {
183 printf("%s\n",bp->bottom_message);
184 }
185 printf(">> ");
186 } else { /* GRAPHICS_MODE */
187 popupBox(bp->x, bp->y, bp->w, bp->h, TEXT_BG, POPUP_OUT);
188 copyImage(&ns_logo_bitmap, bp->x + BROWSER_XMARGIN,
189 bp->y + BROWSER_YMARGIN + (bp->top_h - ns_logo_bitmap_HEIGHT)/2 );
190 blit_string(bp->top_message,
191 bp->x + ns_logo_bitmap_WIDTH + 2 * BROWSER_XMARGIN,
192 bp->y + (bp->top_h / 2) + BROWSER_YMARGIN,
193 TEXT_FG, CENTER_V);
194 if (bp->bottom_message)
195 blit_string(bp->bottom_message,
196 bp->x + bp->w / 2, bp->bottom_y + bp->bottom_h / 2,
197 TEXT_FG, CENTER_H | CENTER_V);
198 drawButton(&bp->button);
199 /* draw all items and highlight item 0 */
200 if (bp->nitems) {
201 popupBox(bp->item_box_x, bp->item_box_y,
202 bp->item_box_w, bp->item_box_h,
203 TEXT_BG, POPUP_IN);
204 drawItembox(bp);
205 }
206 }
207}
208
209clearBrowser(browser_t *bp)
210{
211 if (currentMode() == GRAPHICS_MODE)
212 clearBox(bp->x, bp->y, bp->w, bp->h);
213}
214
215
216selectItem(browser_t *bp, int item)
217{
218 int i;
219 if (bp->selected[item] == 0 &&
220 (bp->type == BROWSER_CURRENT_IS_SELECTED)) {
221 for (i=0; i < bp->nitems; i++)
222 if (bp->selected[i]) {
223 bp->selected[i] = 0;
224 setItemHighlight(bp, i, i == bp->current);
225 }
226 }
227 bp->selected[item] = !bp->selected[item];
228 setItemHighlight(bp, item, item == bp->current);
229}
230
231runBrowser(browser_t *bp)
232{
233 int c, i;
234 char *s;
235
236 if (bp->nitems == 0) {
237 while ((c = getc() != '\r'));
238 putc('\n');
239 return;
240 }
241
242 if (currentMode() == TEXT_MODE) {
243 s = zalloc(128);
244 for(;;) {
245 gets(s, 128);
246 if ((*s == 'f') || (*s == 'F')) {
247 if (currentMode() == TEXT_MODE)
248 if (bp->bot_visible != bp->nitems - 1) {
249 bp->top_visible += MAX_ITEMS_VISIBLE;
250 bp->bot_visible += MAX_ITEMS_VISIBLE;
251 bp->bot_visible = min(bp->nitems - 1, bp->bot_visible);
252 drawBrowser(bp);
253 continue;
254 }
255 } else if ((*s == 'b') || (*s == 'B')) {
256 if (currentMode() == TEXT_MODE)
257 if (bp->top_visible >= MAX_ITEMS_VISIBLE) {
258 bp->top_visible -= MAX_ITEMS_VISIBLE;
259 bp->bot_visible = bp->top_visible +
260 MAX_ITEMS_VISIBLE - 1;
261 drawBrowser(bp);
262 continue;
263 }
264 }
265 if (*s == '\0')
266 return;
267 i = atoi(s);
268 if (i < 1 || i > bp->nitems) {
269 printf("Please enter a number between 1 and %d.\n"
270 "Press <Return>:",
271 bp->nitems);
272 while ((c = getc()) != '\r');
273 } else {
274 selectItem(bp, i-1);
275 }
276 drawBrowser(bp);
277 }
278 zfree(s);
279 return;
280 }
281
282 for(;;) {
283 switch((c = getc())) {
284 case 'j':
285 case K_DOWN:
286 if (bp->current == bp->bot_visible &&
287 bp->bot_visible != bp->nitems - 1) {
288 bp->top_visible++;
289 bp->bot_visible++;
290 bp->current++;
291 if (bp->type == BROWSER_CURRENT_IS_SELECTED)
292 selectItem(bp, bp->current);
293 drawItembox(bp);
294 } else if (bp->current < bp->nitems - 1) {
295 setItemHighlight(bp, bp->current, 0);
296 bp->current++;
297 if (bp->type == BROWSER_CURRENT_IS_SELECTED)
298 selectItem(bp, bp->current);
299 else
300 setItemHighlight(bp, bp->current, 1);
301 }
302 break;
303 case 'k':
304 case K_UP:
305 if (bp->current == bp->top_visible &&
306 bp->top_visible != 0) {
307 bp->top_visible--;
308 bp->bot_visible--;
309 bp->current--;
310 if (bp->type == BROWSER_CURRENT_IS_SELECTED)
311 selectItem(bp, bp->current);
312 drawItembox(bp);
313 } else if (bp->current > 0) {
314 setItemHighlight(bp, bp->current, 0);
315 bp->current--;
316 if (bp->type == BROWSER_CURRENT_IS_SELECTED)
317 selectItem(bp, bp->current);
318 else
319 setItemHighlight(bp, bp->current, 1);
320 }
321 break;
322 case ' ':
323 if (!(bp->type == BROWSER_CURRENT_IS_SELECTED))
324 selectItem(bp, bp->current);
325 break;
326 case '\r':
327 case '\n':
328 return;
329 }
330 }
331}
332
333static browser_t *_doBrowser(
334 char **items,
335 int nitems,
336 char *top_message,
337 char *bottom_message,
338 char *button_string,
339 int type
340)
341{
342 browser_t *bp;
343
344 bp = createBrowser(items, nitems,
345 top_message, bottom_message, button_string, type);
346 drawBrowser(bp);
347 runBrowser(bp);
348 clearBrowser(bp);
349 return bp;
350}
351
352/*
353 * returns an array of characters, one per item,
354 * that are set to 0 if the item was not selected,
355 * 1 if the item was selected.
356 */
357char * popupBrowser(
358 char **items,
359 int nitems,
360 char *top_message,
361 char *bottom_message,
362 char *button_string,
363 int type
364)
365{
366 browser_t *bp;
367 register char *selected;
368
369 bp = _doBrowser(items, nitems,
370 top_message, bottom_message, button_string, type);
371 selected = bp->selected;
372 destroyBrowser(bp);
373 return selected;
374}
375
376void popupPanel(
377 char *message
378)
379{
380 browser_t *bp;
381
382 bp = _doBrowser(0, 0,
383 message, 0, "Continue", 0);
384 zfree(bp->selected);
385 destroyBrowser(bp);
386}
387
388