/* update graphics, will return none-zero if an update is required */ uint8_t update_graphics(void) { if ( m2_GetRoot() == &el_combine ) { /* "combine graphics" is active, update the rectangle for animation */ return update_rectangle(); } if ( m2_GetRoot() == &m2_null_element ) { /* check for any keys and assign a suitable menu again */ if ( m2_GetKey() != M2_KEY_NONE ) m2_SetRoot(&el_top); /* all menus are gone, rectangle is shown, so do update */ return update_rectangle(); } /* no update for the graphics required */ return 0; }
/* if prompt is zero then we are really a menu */ word open_dialog(char *title, word width, word height, char *prompt) { word num; if ( (num=spare_window())==-1) return ERRM_NOSPARE; dlog=wlist[num]; /* centered on screen */ dlog->x=(maxw-width-2)/2; dlog->y=(maxh-height-2)/2; dlog->w=width+2; dlog->h=height+2; dlog->open=TRUE; dlog->number=num; dlog->type=WTYPE_DIALOG; dlog->magic=NULL; add_wlist(dlog); /* mark us on the screen, carefully as we are not in the wlist */ window_cls(dlog); window_title2(dlog,title,FALSE); recalcw(dlog); update_rectangle(dlog->x,dlog->y,dlog->w,dlog->h); line_buffer=dlog_line; /* where it will be remembered */ if (prompt) { winit_command(dlog); if (dlog->type==WTYPE_NONE) { close_dialog(); return ERRM_NOMEMORY; } print_dialog(1,prompt); /* print prompt */ dlog->xpos=DLOGX; dlog->ypos++; start_command(dlog,""); } return 0; }
void close_dialog() { wdeinit_command(dlog); dlog->open=FALSE; remove_wlist(dlog); /* restore correct view of world */ recalc_frontback(); /* and redraw this new place */ update_rectangle(dlog->x, dlog->y, (word)(dlog->x+dlog->w), (word)(dlog->y+dlog->h) ); }
/* 2nd line is optional */ word general_alert(char *title, char *line1, char *line2, const char *keylist, word *res) { word width,height; word num; struct ws *alertw; word key,mx,my,ev; word err; width=strlen(line1); height=5; if (line2) { width=max(width,strlen(line2)); height+=2; } width+=4; width=min(maxw,width); if ( (num=spare_window())==-1) return ERRM_NOSPARE; alertw=wlist[num]; /* centered on screen */ alertw->x=(maxw-width)/2; alertw->y=(maxh-height)/2; alertw->w=width; alertw->h=height; alertw->open=TRUE; alertw->number=num; alertw->type=WTYPE_DIALOG; alertw->magic=NULL; add_wlist(alertw); /* mark us on the screen, carefully as we are not in the wlist */ window_cls(alertw); window_title2(alertw,title ? title : "",FALSE); recalcw(alertw); update_rectangle(alertw->x,alertw->y,alertw->w,alertw->h); alertw->xpos=2; alertw->ypos=2; wprint_str(line1); if (line2) { alertw->xpos=2; alertw->ypos+=2; wprint_str(line2); } for (;;) { err=0; ev=get_event(&key,&mx,&my); if (keylist) { if (ev&EV_KEY) { char *match; if (key==KEY_ESC) { err=ERRM_INTERRUPTED; break; } key=toupper(key&0xFF); if (match=strchr(keylist,key)) { *res=(word)(match-keylist); break; /* returns 0 */ } } } else if (ev&(EV_KEY|EV_CLICK)) break; /* any key exits or a click */ } remove_wlist(alertw); alertw->open=FALSE; /* restore correct view of world */ recalc_frontback(); /* and redraw this new place */ update_rectangle(alertw->x, alertw->y, (word)(alertw->x+alertw->w), (word)(alertw->y+alertw->h) ); return err; }
word do_menu(char *title, word width, word height, char *list[], word *result, bool(*reload)(char*, word*), char *preload ) { word i; word ev,key,mx,my; word currenty,currentx; word visible; word num; struct ws *menuw; char menu_so_far[MAXMENUWIDTH+1]; /* can, in theory, recurse */ word numlist; if (preload==NULL) menu_so_far[0]=0; else { stccpy(menu_so_far,preload,MAXMENUWIDTH); strupr(menu_so_far); } currentx=strlen(menu_so_far); (reload)(menu_so_far,&numlist); /* initial value */ if (numlist==0) { *result=-1; return 0; } if ( (num=spare_window())==-1) return ERRM_NOSPARE; if (width>MAXMENUWIDTH) width=MAXMENUWIDTH; menuw=wlist[num]; /* centered on screen */ menuw->x=(maxw-width-2)/2; menuw->y=(maxh-height-2)/2; menuw->w=width+2; menuw->h=height+2; menuw->open=TRUE; menuw->number=num; menuw->type=WTYPE_DIALOG; menuw->magic=NULL; add_wlist(menuw); /* mark us on the screen, carefully as we are not in the wlist */ window_cls(menuw); window_title2(menuw,title,FALSE); recalcw(menuw); update_rectangle(menuw->x,menuw->y,menuw->w,menuw->h); for (;;) { p: visible=min(height,numlist); currenty=0; /* print the entries */ for (i=0; i<visible; i++) { menuw->xpos=DLOGX; menuw->ypos=i+1; wprint_str(list[i]); } k: if (visible) light_line(currenty,(word)(currentx+1),(word)(width-currentx-1)); else light_line(currenty,1,(word)(width-1)); ev=get_event(&key,&mx,&my); if (visible) light_line(currenty,(word)(currentx+1),(word)(width-currentx-1)); else light_line(currenty,1,(word)(width-1)); if (ev&EV_CLICK) { word w; ubyte edge; if (visible) { w=which_window(&mx,&my,&edge); if ( (w==num) && (edge==0) && (my<=visible) ) { if (key) { /* a double-click */ key=KEY_RETURN; break; } currenty=--my; goto k; } } } if (ev&EV_KEY) { if ( (key==KEY_UP) && (currenty) && visible ) { currenty--; goto k; } if ( (key==KEY_DOWN) && visible && (currenty<(visible-1)) ) { currenty++; goto k; } if ( (key==KEY_RETURN) || (key==KEY_ENTER) || (key==KEY_ESC) ) break; if (reload) { if (key==KEY_BACKSPACE) { if (currentx) menu_so_far[--currentx]=0; } else if (key==KEY_CLEAR) { menu_so_far[currentx=0]=0; } else if (key&0xFF) { if (currentx<MAXMENUWIDTH) menu_so_far[currentx++]=upper((char)key); menu_so_far[currentx]=0; } else goto k; if ( (reload)(menu_so_far,&numlist) ) { window_cls(menuw); update_contents(menuw); goto p; } else goto k; } } goto k; } /* like close_dialog */ remove_wlist(menuw); menuw->open=FALSE; /* restore correct view of world */ recalc_frontback(); /* and redraw this new place */ update_rectangle(menuw->x, menuw->y, (word)(menuw->x+menuw->w), (word)(menuw->y+menuw->h) ); *result=( (key==KEY_ESC) || (visible==0) ) ? -2 : currenty; return 0; }