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