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 
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 
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 
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 
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 
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 
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 
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