#include #include #include #include #define up 0x4800 #define down 0x5000 #define left 0x4b00 #define right 0x4d00 #define esc 0x011b #define bs 0x0e08 #define del 0x5300 #define cr 0x1c0d typedef struct MenuTag{ char *Title; void (*Func)(struct MenuTag *m); struct MenuTag *Sub; int Sel,x,y; } Menu; typedef struct scr_tag { int x,y,x1,y1,x2,y2; struct scr_tag* prev; } Scr; Scr* SCR_S = 0; int keys[30], keyp=0; getkey() { int key; if (keyp) key = keys[--keyp]; else { while (!bioskey(1)) { sound(1000); delay(10); nosound(); } key = bioskey(0); } return key; } ungetkey(int key) { if (keyp >= 30) return; keys[keyp++] = key; } void DisTop(Menu *m) { int xlen, ylen, xpos; int i, j, k; int exit = 0; int Scr[80]; m->Sel = 0; for (ylen = xlen=0; m->Sub[ylen].Title; ylen++) xlen = max(xlen, strlen(m->Sub[ylen].Title)); pushscr(1,1,80,1); while( ! exit) { for (k=i=0; iSel) xpos = k; for (j=0; m->Sub[i].Title[j]; j++) Scr[k++] = m->Sub[i].Title[j] + (i == m->Sel ? 0x7e00 : 0x6e00); Scr[k++] = 0x6e00 + ' '; } k--; while (k<80) Scr[k++] = 0xe00 + ' '; puttext(1,1,80,1,Scr); switch( i = getkey()) { case left : if (--m->Sel < 0) m->Sel = ylen - 1; break; case right : if (++m->Sel >= ylen) m->Sel = 0; break; case esc : exit = -1 ; break; case cr : m->Sub[m->Sel].x = xpos; m->Sub[m->Sel].y = 2; m->Sub[m->Sel].Func(&m->Sub[m->Sel]); break; } } popscr(); } pushscr(int x1,int y1,int x2, int y2) { Scr *m = (Scr*)malloc(sizeof(*m) + (x2 - x1 + 1) * (y2 - y1 + 1) * 2); if (m) { gettext(x1,y1,x2,y2, (void*)(m+1)); m->x = wherex(); m->y = wherey(); m->x1 = x1; m->y1 = y1; m->x2 = x2; m->y2 = y2; m->prev = SCR_S; SCR_S = m; } return !!m; } popscr() { Scr *m = SCR_S; if (m) { SCR_S = m->prev; puttext(m->x1, m->y1, m->x2, m->y2, (void*)(m+1)); gotoxy(m->x,m->y); free(m); } return !!m; } Box(int x0, int y0, int x1, int y1, int color) { int xlen = x1 - x0 + 1, ylen = y1 - y0 + 1; int x, y ; int *scr = malloc(xlen*ylen*2); scr[0] = 'É' + color; scr[xlen - 1] = '»' + color; scr[xlen * ylen-1] = '¼' + color; scr[xlen * (ylen-1)] = 'È' + color; for (x=1; xSel) scr[y*xlen+x] = 0x7e00 + (strlen(m->Sub[y].Title) < x ? ' ' : m->Sub[y].Title[x]); else scr[y*xlen+x] = 0x6e00 + (strlen(m->Sub[y].Title) < x ? ' ' : m->Sub[y].Title[x]); } Box(m->x+3,m->y,xlen+1+m->x+3,ylen+1+m->y,0x6f00); puttext(m->x+4,m->y+1,xlen+m->x+3,ylen+m->y,scr); free(scr); return ; } void SubMenu(Menu *m) { int xlen; int ylen; int i; int exit = 0; m->Sel = 0; for (ylen = xlen=0; m->Sub[ylen].Title; ylen++) xlen = max(xlen, strlen(m->Sub[ylen].Title)); pushscr(m->x+3, m->y, m->x + xlen + 4, m->y + ylen + 1); while( ! exit) { DispMenu(m, xlen, ylen); switch( i = getkey()) { case up : if (--m->Sel < 0) m->Sel = ylen - 1; break; case down : if (++m->Sel >= ylen) m->Sel = 0; break; case esc : exit = -1 ; break; case cr : m->Sub[m->Sel].x = m->x + 6; m->Sub[m->Sel].y = m->y + m->Sel + 2; m->Sub[m->Sel].Func(&m->Sub[m->Sel]); break; case left : ungetkey(cr); ungetkey(left); ungetkey(esc); break; case right : ungetkey(cr); ungetkey(right); ungetkey(esc); break; } } popscr(); } void NewF(Menu *m){} void OpenF(Menu *m){} void SaveF(Menu *m){} void FindF(Menu *m){} void ReplaceF(Menu *m){} void SearchAgainF(Menu *m){} void GoF(Menu *m){} void ResetF(Menu *m){} void StepF(Menu *m){} void ModelF(Menu *m){} void DefineF(Menu *m){} void CodeF(Menu *m){} void LinkerF(Menu *m){} void MessageF(Menu *m){} void KeepMessageF(Menu *m){} void ConfigAutoSaveF(Menu *m){} Menu File[] = { {"New",NewF}, {"Open",OpenF}, {"Save",SaveF},0}; Menu Search[]= { {"Find",FindF}, {"Replace",ReplaceF}, {"SearchAgain",SearchAgainF},0}; Menu Run[] = { {"Go",GoF}, {"Reset",ResetF}, {"Step",StepF},0}; Menu Comp[] = { {"Model",ModelF}, {"Define",DefineF}, {"Code",CodeF},0}; Menu Envir[] = { {"Message",MessageF}, {"Keep message",KeepMessageF}, {"Config auto save",ConfigAutoSaveF},0}; Menu Option[]= { {"Compiler",SubMenu,Comp}, {"Linker",LinkerF}, {"Environment",SubMenu,Envir},0}; Menu Main[] = { {"File",SubMenu,File}, {"Search",SubMenu,Search}, {"Run",SubMenu,Run}, {"Option",SubMenu,Option},0}; void main() { int i; Menu MMain = {"Main",DisTop,Main,0,1,1}; pushscr(1,1,80,25); MMain.Func(&MMain); popscr(); }