1 /* @(#)menu.c 1.2 04/18/83
2 *
3 * Copyright -C- 1982 Barry S. Roitblat
4 *
5 *
6 * This file contains the routines for initializing and displaying
7 * the graphics menu.
8 */
9
10 #include "gremlin.h"
11
12 /* imports from graphics1.c */
13
14 extern GRchex(); /* hex conversion routine */
15 extern GRsetpos(); /* sets the current access position */
16 extern GRVector(); /* vector drawing primitive */
17 extern int GrXMax, GrYMax; /* screen dimensions */
18 extern FILE *display; /* graphics display stream */
19 extern GRDisableTablet(); /* disable graphics tablet */
20
21 /* imports from long.c */
22
23 extern LGCommand(), LGPoint(), LGUndo(), LGDeletePoint();
24
25 /* imports from short.c */
26
27 extern SHCommand();
28
29 /* imports from main.c */
30
31 extern float PX, PY; /* X and Y of last points specified */
32
33 #define horiz 0
34 #define vert 1
35 #define menusize 32
36 #define menuspace 30
37 #define origin 10
38 #define margin 25
39 #define itemxsize 16
40 #define itemysize 16
41 #define fontsize (itemxsize * itemysize/8)
42 #define itemlength (itemxsize * itemysize/4 + 1)
43 #define maxchars 8
44 #define smask 1
45 #define columns 2
46 #define border 395
47
48
49 /* bytewise definitions of menu symbols (special fonts), left to right,
50 * top to bottom. See textcommand array for corresponding commands.
51 */
52
53 static char menu[menusize][itemlength] =
54 {
55 /* 1 */ "07F00080008000800080008000800080008000800080008000800080008007F0",
56 /* 2 */ "08100810082008200840084008800F0008C00820081008100810082008C00F00",
57 /* 3 */ "0000000000000000000000000000FFFFFFFFFFFF000000000000000000000000",
58 /* 4 */ "0000000000000000000000000000E4E4E4E40000000000000000000000000000",
59 /* 5 */ "0000000000000000000000000000924992490000000000000000000000000000",
60 /* 6 */ "FFFF8001800187E18401840183018081804180218421842183C180018001FFFF",
61 /* 7 */ "FFFF80018001808180818081808180818081808182818181808180018001FFFF",
62 /* 8 */ "008001C002A0008000800080008000800080008000800080008002A001C00080",
63 /* 9 */ "00000000000000000000000020044002FFFF4002200400000000000000000000",
64 /* 10 */ "000080028002400440042008183007C0FFFF07C0183020084004400480028002",
65 /* 11 */ "20002000FFFC2704288430443044304428842704200427C424443FFF044407C4",
66 /* 12 */ "FFFF804080E0815080408080808081008600F800800080008000800080008000",
67 /* 13 */ "00FF008100810081008100810E8106FF0A00100020000000F00090009000F000",
68 /* 14 */ "FFFF8001A001900180018401820180018001804180218001800980058001FFFF",
69 /* 15 */ "000000000000000030001C000B800460021804600B801C003000000000000000",
70 /* 16 */ "00000000000000001C02220143018101808180C2804440380000000000000000",
71 /* 17 */ "03C004200010001000100010002003C004000800080008000800042003C00000",
72 /* 18 */ "0F0008C008200810081008100810082008C00F0008C008200820082008C00F00",
73 /* 19 */ "00000000000000000000000000000000FFFFFFFF000000000000000000000000",
74 /* 20 */ "00000000000000000000000000000000FFFF0000000000000000000000000000",
75 /* 21 */ "00000000000000000000000000000000F87C0000000000000000000000000000",
76 /* 22 */ "FFFF800180018041804180418041804187E1844184418441804180018001FFFF",
77 /* 23 */ "FFFF80018001838184418821802180418181804180218821844183818001FFFF",
78 /* 24 */ "80028002400440042008183007C001000280044008201EF00280028002800280",
79 /* 25 */ "000400023FFF2002200420002000200020002000200020002000A80070002000",
80 /* 26 */ "20042004FFFF2004200420042004200420042004200420042004FFFF20042004",
81 /* 27 */ "FFFF9C39A245C183C183C183A2459C3981C18221841184118411822181C1FFFF",
82 /* 28 */ "800140023FFC300C28142424224421842184224424242814300C3FFC40028001",
83 /* 29 */ "000000000000000F00090009F04F902097F0F02F00490009000F000000000000",
84 /* 30 */ "F00090009000F000080004000200014000C001C00000001E00120012001E0000",
85 /* 31 */ "000007C0183020084004400480028002810280028002400440042008183007C0",
86 /* 32 */ "02000100FF80018002400040002000200010001000082019400EFFFC40002000"
87 };
88
89 /* menu item color map */
90
91 static int mencolor[menusize] = {
92 4, 1, 3, 1, 1, 6, 6, 1, 1, 5, 5, 5, 5, 3, 3, 3, 6, 5, 2, 1, 1, 6, 6, 1, 1, 1,
93 5, 5, 5, 5, 3, 3 };
94
95 /* menu equivalent text commands */
96
97 static char textcommand[menusize][maxchars] =
98 {
99 /* 1 */ ":f,2", /* font,2 */
100 /* 2 */ ":f,1", /* font,1 */
101 /* 3 */ ":br,3", /* brush,3 */
102 /* 4 */ ":br,2", /* brush,2 */
103 /* 5 */ ":br,1", /* brush,1 */
104 /* 6 */ ":buf,2", /* set buffer 2 */
105 /* 7 */ ":buf,1", /* set buffer 1 */
106 /* 8 */ ":vadj", /* vertical adjust */
107 /* 9 */ ":hadj", /* horizontal adjust */
108 /* 10 */ ":mi", /* mirror */
109 /* 11 */ "f", /* select area in current set */
110 /* 12 */ "r", /* rotate current set */
111 /* 13 */ "s", /* scale current set */
112 /* 14 */ "x", /* rectangle from 2 points */
113 /* 15 */ "w", /* arrow heads */
114 /* 16 */ "b", /* draw curve */
115 /* 17 */ ":f,4", /* font,4 */
116 /* 18 */ ":f,3", /* font,3 */
117 /* 19 */ ":br,6", /* brush,6 */
118 /* 20 */ ":br,5", /* brush,5 */
119 /* 21 */ ":br,4", /* brush,4 */
120 /* 22 */ ":buf,4", /* set buffer 4 */
121 /* 23 */ ":buf,3", /* set buffer 3 */
122 /* 24 */ "g", /* gravity */
123 /* 25 */ "z", /* manhattan adjust */
124 /* 26 */ "q", /* grid */
125 /* 27 */ "d", /* define current set */
126 /* 28 */ "e", /* erase */
127 /* 29 */ "c", /* copy current set */
128 /* 30 */ "t", /* translate current set */
129 /* 31 */ "a", /* draw arc */
130 /* 32 */ "v", /* draw vector */
131 };
132
133 /* screen map for menu symbols */
134
135 struct bounds
136 {
137 int lowx, lowy, hix, hiy;
138 };
139
140 static struct bounds area[menusize];
141
142 /* Following is a map of brushes and mode made available to the
143 * outside world for selection of these items for highlighting.
144 * The numbers indicate the items location in the menu.
145 */
146
147 int HiMen[4] = { 6, 5, 22, 21 }; /* user symbols */
148 int HiFont[4] = { 1, 0, 17, 16}; /* fonts */
149 int HiBrush[6] = { 4, 3, 2, 20, 19, 18 }; /* brushes */
150 int HiMode[4] = { 8, 7, 24, 23 }; /* horz, vert, man, grav. */
151
152 static int xorig, yorig, deltax, deltay;
153 static POINT bord1, bord2;
154
155 /* forward references within this file */
156
157 extern MNHighLt(), MNUnHighLt();
158 /* variables to save previous command */
159
160 static char *last;
161 static lastint;
162
MNIcon()163 MNIcon()
164 /*
165 * This routine initializatizes the menu symbols by defining to
166 * the AED each menu symbol as a special font. The special fonts are
167 * defined by a series of bytes in the array menu which is initialized.
168 * they could also be read in from an external file.
169 */
170
171 {
172 int i;
173
174 #ifndef FASTIO
175 char s1[3], s2[3], s3[3], s4[3];
176 #else
177 int c, k;
178 #endif
179
180 /* add code here to read in special fonts if
181 desired. */
182
183 for (i=1; i<=menusize; ++i)
184 {
185 putc('7',display); /* define special font */
186
187 #ifndef FASTIO
188 GRchex(i,s1,2);
189 GRchex(itemxsize,s2,2);
190 GRchex(itemysize,s3,2);
191 GRchex(mencolor[i-1],s4,2);
192 fprintf(display,"%s%s%s%s%s00",s1,s2,s3,s4,menu[i-1]);
193 #else
194 fprintf(display,"%c%c%c%c",i&0377, itemxsize&0377,
195 itemysize&0377, mencolor[i-1]&0377);
196 for (k=0; k<itemlength-1; k+=2)
197 {
198 (void) sscanf(&(menu[i-1][k]),"%2x",&c);
199 putc(c&0377,display);
200 }; /* end for k */
201 putc('\0',display);
202 #endif
203
204 }; /* end for i */
205 (void) fflush(display);
206 }; /* end Icon */
207
208
MNInitMenu(orientation)209 MNInitMenu(orientation)
210 int orientation; /* orientation of work space */
211 /*
212 * This routine initializatizes the spacing and orientation of
213 * the menu so that elements can be properly displayed and selected.
214 */
215
216 {
217 int xcum, ycum, i;
218
219 last = textcommand[0];
220 lastint = 0;
221
222 if (orientation == horiz) /* set up spacing for menu display */
223 {
224 xorig = GrXMax - origin - menuspace;
225 yorig = GrYMax - menuspace;
226 deltax = -menuspace;
227 deltay = 0;
228 bord1.y = bord2.y = border;
229 bord1.x = 0;
230 bord2.x = GrXMax;
231 }
232 else
233 {
234 xorig = margin ;
235 yorig = origin;
236 deltax = 0;
237 deltay = menuspace;
238 bord1.x = bord2.x = GrXMax - border;
239 bord1.y = 0;
240 bord2.y = GrYMax;
241 };
242 xcum = xorig - (menuspace - itemxsize)/2;
243 ycum = yorig - (menuspace - itemysize)/2;
244
245 for (i=0; i<menusize; ++i) /* store boundaries for each menu item */
246 {
247 area[i].lowx = xcum;
248 area[i].lowy = ycum;
249 area[i].hix = xcum + menuspace;
250 area[i].hiy = ycum + menuspace;
251 xcum += deltax;
252 ycum += deltay;
253 if (((i+1)%(menusize/columns)) == 0) /* end of row/col */
254 {
255 xcum = xorig + deltay - (menuspace - itemxsize)/2;
256 ycum = yorig + deltax - (menuspace - itemysize)/2;
257 } /* end if */;
258 } /* end for */;
259 } /* end initmenu */
260
261
MNDisplayMenu()262 MNDisplayMenu()
263 /*
264 * This routine displays the menu defined by initmenu
265 */
266
267 {
268 int i;
269
270 #ifndef FASTIO
271 char s1[3], s2[3], s3[3];
272 #endif
273
274 GRsetpos(xorig, yorig);
275 putc('8',display); /* write special font */
276 for (i=1; i<=menusize; ++i)
277 {
278
279 #ifndef FASTIO
280 GRchex(i,s1,2);
281 GRchex(deltax,s2,2);
282 GRchex(deltay,s3,2);
283 fprintf(display,"%s%s%s", s1, s2, s3);
284 #else
285 fprintf(display,"%c%c%c",i&0377, deltax&0377, deltay&0377);
286 #endif
287 (void) fflush(display);
288 if ((i%(menusize/columns)) == 0) /* new row/col */
289 {
290
291 #ifndef FASTIO
292 fputs("00",display);
293 #else
294 putc('\00',display);
295 #endif
296
297 GRsetpos(xorig+deltay, yorig+deltax); /* reposition */
298 putc('8',display);
299 } /* end if */;
300 } /* end for */
301
302 #ifndef FASTIO
303 fputs("00",display);
304 #else
305 putc('\00',display);
306 #endif
307
308 GRsetwmask(linemask);
309 GRVector(&bord1, &bord2, bordstyle);
310 } /* end displaymenu */;
311
312
MNFindMenuItem(x,y)313 char *MNFindMenuItem(x,y)
314 int x, y;
315 /*
316 * returns a pointer to the text string equivalent of the selected
317 * menu item.
318 */
319
320 {
321 int i;
322
323 for (i=0; i<menusize; ++i)
324 if (x < area[i].hix)
325 if (y < area[i].hiy)
326 if (x > area[i].lowx)
327 if (y > area[i].lowy)
328 {
329 last = textcommand[i];
330 lastint = i;
331 return(textcommand[i]);
332 } /* end, nested if */;
333
334 return(last); /* cursor out of menu area */
335 } /* end findmenuitem */
336
MNHighLt(sym,color)337 MNHighLt(sym,color)
338 int sym, color;
339 /*
340 * This routine highlights the specified menu item by drawing a
341 * box around it in the highlighting color.
342 */
343
344 {
345 POINT p1, p2, p3, p4;
346
347 GRsetwmask(himask);
348 p1.x = area[sym].lowx;
349 p1.y = area[sym].lowy;
350 p2.x = area[sym].lowx;
351 p2.y = area[sym].hiy - 1;
352 p3.x = area[sym].hix - 1;
353 p3.y = area[sym].hiy - 1;
354 p4.x = area[sym].hix - 1;
355 p4.y = area[sym].lowy;
356 GRVector(&p1, &p2, color);
357 GRVector(&p2, &p3, color);
358 GRVector(&p3, &p4, color);
359 GRVector(&p4, &p1, color);
360 } /* end MNHighLt */
361
MNUnHighLt(sym)362 MNUnHighLt(sym)
363 int sym;
364 /*
365 * This routine unhighlights the specified symbol by calling
366 * MNHighLt with the erase color specified.
367 */
368
369 {
370 MNHighLt(sym, eraseany);
371 }
372
373
MNInterpretCursor(button,cx,cy)374 MNInterpretCursor(button, cx, cy)
375 int cx, cy, button;
376 /*
377 * This routine interprets the cursor button function and calls
378 * the appropriate command interpretation routines.
379 */
380
381 {
382 char *cmd;
383
384 PX = cx;
385 PY = cy;
386 if (button == 0)
387 {
388 cmd = MNFindMenuItem(cx, cy);
389 if (*cmd == ':') LGCommand(++cmd);
390 else SHCommand(cmd);
391 }
392 if (button == 1) LGDeletePoint(++cmd);
393 if (button == 2) LGUndo(++cmd);
394 if (button == 3)
395 {
396 LGPoint(++cmd);
397 }
398 }
399