/* * MENU.C * * Menu routines... made to take up as little space as possible, and * thus uses many tricks which you should watch out for. */ #include "defs.h" typedef struct { ITEM item; char *com; } XITEM; short Menuoff; short DoMenuoff; MENU *Menu; extern XITEM *ItemAddress(); menu_strip(win) WIN *win; { if (!Menuoff && Menu) { SetMenuStrip(win,Menu); Forbid(); win->Flags &= ~RMBTRAP; Permit(); } } menu_off() { register ED *ed; if (Menuoff == 0) { for (ed = Base; ed; ed = ed->next) { ClearMenuStrip(ed->Win); Forbid(); ed->Win->Flags |= RMBTRAP; Permit(); } } ++Menuoff; } menu_on() { register ED *ed; if (Menu && Menuoff == 1) { fixmenu(); for (ed = Base; ed; ed = ed->next) { SetMenuStrip(ed->Win,Menu); Forbid(); ed->Win->Flags &= ~RMBTRAP; Permit(); } } --Menuoff; } do_menuoff() { menu_off(); ++DoMenuoff; } do_menuon() { if (DoMenuoff) { --DoMenuoff; menu_on(); } } char * menutomacro(str) char *str; { char header[64]; char itembuf[64]; register short i; register char *ptr; register MENU *menu; register ITEM *item; for (i = 0; str[i] && str[i] != '-'; ++i); if (str[i] == '-') { strncpy(header, str, i); header[i] = 0; strcpy(itembuf, str + i + 1); for (menu = Menu; menu; menu = menu->NextMenu) { if (ncstrcmp(header, menu->MenuName) == 0) { for (item = menu->FirstItem; item; item = item->NextItem) { ptr = (char *)((ITEXT *)item->ItemFill)->IText; if (ncstrcmp(itembuf, ptr) == 0) { ptr = ((XITEM *)item)->com; goto done; } } } } } ptr = NULL; done: return(ptr); } char * menu_cmd(im) IMESS *im; { XITEM *item; char *ptr; if (item = ItemAddress(Menu, im->Code)) return(item->com); return(NULL); } fixmenu() { register MENU *menu; register ITEM *item; register ITEXT *it; register int row, col, maxc, scr; col = 0; for (menu = Menu; menu; menu = menu->NextMenu) { maxc = strlen(menu->MenuName); row = 0; for (item = menu->FirstItem; item; item = item->NextItem) { it = (ITEXT *)item->ItemFill; item->TopEdge = row; scr = strlen(((ITEXT *)item->ItemFill)->IText); if (scr > maxc) maxc = scr; item->Height = 10; row += item->Height; } maxc = (maxc * 8) + 16; for (item = menu->FirstItem; item; item = item->NextItem) item->Width = maxc; menu->Width = maxc; menu->LeftEdge = col; menu->Height = row; col += maxc; } } /* * menuclear * menuadd header item command * menudel header item * menudelhdr header */ do_menuclear() { menu_off(); while (Menu) { av[1] = (ubyte *)Menu->MenuName; do_menudelhdr(); } menu_on(); } do_menuadd() { register MENU *menu, **mpr; register ITEM *item, **ipr; register ITEXT *it; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { if (strcmp(av[2], ((ITEXT *)item->ItemFill)->IText) == 0) goto newname; ipr = &item->NextItem; } goto newitem; } mpr = &menu->NextMenu; } newmenu: /* create new menu */ menu = malloc(sizeof(MENU)); bzero(menu, sizeof(MENU)); menu->NextMenu = *mpr; *mpr = menu; menu->Flags = MENUENABLED; menu->MenuName = malloc(strlen(av[1])+1); strcpy(menu->MenuName, av[1]); ipr = &menu->FirstItem; *ipr = NULL; newitem: /* create new item */ it = malloc(sizeof(ITEXT)); bzero(it, sizeof(ITEXT)); it->BackPen = 1; it->DrawMode = JAM2; it->IText = malloc(strlen(av[2])+1); strcpy(it->IText, av[2]); item = malloc(sizeof(XITEM)); bzero(item, sizeof(XITEM)); item->NextItem = *ipr; *ipr = item; item->ItemFill = (APTR)it; item->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP; newname: /* create new name */ if (((XITEM *)item)->com) free(((XITEM *)item)->com); ((XITEM *)item)->com = malloc(strlen(av[3])+1); strcpy(((XITEM *)item)->com, av[3]); menu_on(); } do_menudelhdr() { register MENU *menu; register MENU **mpr; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { if (menu->FirstItem) { while (menu->FirstItem) { av[2] = ((ITEXT *)menu->FirstItem->ItemFill)->IText; if (do_menudel()) break; } break; } *mpr = menu->NextMenu; free(menu->MenuName); free(menu); break; } mpr = &menu->NextMenu; } menu_on(); } do_menudel() { register MENU *menu; register ITEM *item, **ipr; register ITEXT *it; short ret = 0; menu_off(); for (menu = Menu; menu; menu = menu->NextMenu) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { it = (ITEXT *)item->ItemFill; if (strcmp(av[2], it->IText) == 0) { *ipr = item->NextItem; free(it->IText); free(it); free(((XITEM *)item)->com); free(item); if (!menu->FirstItem) { do_menudelhdr(); ret = 1; } menu_on(); return(ret); } ipr = &item->NextItem; } } } menu_on(); return(ret); }