X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fted5%2FMENU.C;fp=16%2Fted5%2FMENU.C;h=63f47a61c287a84b4894551e2e3480988703c78f;hp=0000000000000000000000000000000000000000;hb=4c15d088479b9b6c4a8b298a9db585bc11582321;hpb=21ff8e5607ba86e91ed0d71f6261fd0fcc676e16 diff --git a/16/ted5/MENU.C b/16/ted5/MENU.C new file mode 100755 index 00000000..63f47a61 --- /dev/null +++ b/16/ted5/MENU.C @@ -0,0 +1,1877 @@ +///////////////////////////////////////////////////////////////// +// +// Pull-Down Menu Interface +// by John Romero (C) 1991 Id Software +// +///////////////////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + +#define NUMFLASHES 10 +#define ALT 0x38 +#define CTRL 0x1d + +#define CGASIZE 0x4000 +#define EGA1SIZE 0x2000 +#define EGA2SIZE 0x9600 +#define EGA3SIZE 60000 +#define VGASIZE 64000 + +void (*HookRoutine)(int x,int y); +void (*ItemRoutine)(void); +char MenuStr[20][80],tempstr[80]; +memptr Background[10]; +int WhichBack; +struct { int savex,savey,savew,saveh; } Back[10]; +MBarDef *MBarPtr; +MInfoType MenuInfo[10]; +int ScreenWidth,OpenMenu,NumMenus,ItemOn,KeybdOn; + +void HandleOpenMenu(void (*UserRoutine)(void),int which); +void HandleCloseMenu(void (*UserRoutine)(void)); +void HandleHighlight(void (*UserRoutine)(void)); +int DetectMenu(int x,int y); +void ChangeItem(int newitem); +void ClearScreen(void); +void RedrawDesktop(void); +char *PassScancode(int sc); + +///////////////////////////////////////////////////////////////// +// +// Desktop Event Loop +// +///////////////////////////////////////////////////////////////// +void DeskEventLoop(void (*UserRoutine)(void),void (*ConstantRoutine)(void)) +{ + int buttonstatus=0,oldmenu,olditem; + enum clicks {upup,updown,downup,downdown}; + + if (KeybdOn) + { + HandleOpenMenu(UserRoutine,2); + ChangeItem(1); + } + + MouseShow(); + while(1) + { + int temp=MouseButton()&1,temp1=(MouseButton()>>1)&1; + + sx=0; + sy=3; + + if (!OpenMenu) + ConstantRoutine(); + switch(buttonstatus=((buttonstatus<<1)|temp|temp1)&3) + { + case upup: break; + case updown: HandleOpenMenu(UserRoutine,0); + break; + case downdown: HandleHighlight(UserRoutine); + break; + case downup: HandleCloseMenu(UserRoutine); + if (ItemOn && ItemRoutine) + ItemRoutine(); + ItemOn=0; + break; + } + + if (bioskey(1)) + { + char key=bioskey(1)>>8; + int nitems; + + if (OpenMenu) + { + bioskey(0); + + nitems=(MBarPtr+OpenMenu-1)->num_items; + + switch(key) + { + case 0x48: if (OpenMenu) + if (ItemOn) + if (ItemOn==1) + ChangeItem(nitems); + else + ChangeItem(ItemOn-1); + break; + case 0x50: if (OpenMenu) + if (ItemOn) + if (ItemOn==nitems) + ChangeItem(1); + else + ChangeItem(ItemOn+1); + break; + case 0x1c: oldmenu=OpenMenu; + olditem=ItemOn; + HandleCloseMenu(UserRoutine); + if (ItemOn) + ItemRoutine(); + + break; + case 0x4b: if (OpenMenu) + { + int newmenu; + + ItemOn=0; + if (OpenMenu==1) + newmenu=NumMenus; + else + newmenu=OpenMenu-1; + + HandleCloseMenu(UserRoutine); + HandleOpenMenu(UserRoutine,newmenu); + + ChangeItem(1); + } + break; + case 0x4d: if (OpenMenu) + { + int newmenu; + + ItemOn=0; + if (OpenMenu==NumMenus) + newmenu=1; + else + newmenu=OpenMenu+1; + + HandleCloseMenu(UserRoutine); + HandleOpenMenu(UserRoutine,newmenu); + + ChangeItem(1); + } + break; + case 0x01: if (!OpenMenu) + { + HandleOpenMenu(UserRoutine,oldmenu); + ChangeItem(olditem); + } + break; + } + } + else + { + int i,j,numitems,run=0; + MenuDef *items; + + for (i=0;inum_items; + items=(MBarPtr+i)->menu_def; + + for (j=0;jhotkey==key && (items+j)->hotkey) + { + if (((items+j)->shiftflag) && + (!keydown[(items+j)->shiftflag])) + continue; + + ItemRoutine=(items+j)->routine; + ItemRoutine(); + run=1; + break; + } + if (run) + { + if (bioskey(1)) + bioskey(0); + break; + } + } + if (!run) + UserRoutine(); + } + } + } +} + + + +///////////////////////////////////////////////////////////////// +// +// See if a menu was opened +// +///////////////////////////////////////////////////////////////// +void HandleOpenMenu(void (*UserRoutine)(void),int which) +{ + int x,y,loop,flag,tempx,tempw,maxw,loopsize; + MenuDef *items; + + if (!which) + { + MouseCoords(&x,&y); + if (y>8 && !OpenMenu) + { + UserRoutine(); + return; + } + + flag=DetectMenu(x,y); + if (!flag) return; + } + else + flag=which; + + + tempx=MenuInfo[flag-1].menux; + tempw=MenuInfo[flag-1].menuwidth; + items=(MBarPtr+flag-1)->menu_def; + + sx=tempx+1; + sy=0; + maxw=0; + + MouseHide(); + + + // + // BUILD MENU STRINGS + // + loopsize=(MBarPtr+flag-1)->num_items; + + for (loop=0;loopitem_name); + + len=strlen(MenuStr[loop]); + memset(&MenuStr[loop][len],' ',tempw-len+1); + + switch((items+loop)->shiftflag) + { + case ALT: strcat(MenuStr[loop]," ALT-"); break; + case CTRL:strcat(MenuStr[loop],"CTRL-"); + } + + strcat(MenuStr[loop],PassScancode((items+loop)->hotkey)); + + len=strlen(MenuStr[loop]); + if (len>maxw) + maxw=len; + } + + if (tempx+maxw>ScreenWidth) + tempx=ScreenWidth-1-maxw; + SaveBackground(tempx*8,0,(maxw+1)*8,(MBarPtr+flag-1)->num_items*8+16); + + // + // PRINT MENU STRINGS + // + xormask=0xffff; + print((MBarPtr+flag-1)->menu_name); + xormask=0; + + for (loop=0;loop10) + return 0; + + flag=0; + for (loop=0;loop=MenuInfo[loop].menux && x/8num_items; + tempx=MenuInfo[OpenMenu-1].menux; + tempw=strlen(MenuStr[0])-5; + if (tempx+tempw+5>ScreenWidth) + tempx=ScreenWidth-tempw-5; + + opmen=DetectMenu(x,y); + if (opmen && opmen!=OpenMenu) + { + OpenMenu=0; + RestoreBackground(); + HandleOpenMenu(UserRoutine,0); + return; + } + + // + // IS USER IN A MENU? + // + + if (x/8>tempx && x/88 && y<(nitems+1)*8) + { + if (y/8==ItemOn) + return; // EXIT IF ON SAME ITEM + + // + // IF AN ITEM IS CURRENTLY SELECTED, DEHIGHLIGHT IT + // AND HIGHLIGHT A NEW ITEM + // + + ChangeItem(y/8); + } + else + // + // USER MOVED POINTER OUTSIDE OF MENU; DEHIGHLIGHT ITEM + // + + if (ItemOn) + { + MouseHide(); + + sx=tempx; + sy=ItemOn; + print(MenuStr[ItemOn-1]); + + ItemOn=0; + MouseShow(); + } +} + + + +///////////////////////////////////////////////////////////////// +// +// Set new item highlighted +// +///////////////////////////////////////////////////////////////// +void ChangeItem(int newitem) +{ + int tempx,tempw; + MenuDef *items; + char tempstr[80]=""; + + tempx=MenuInfo[OpenMenu-1].menux; + if (tempx+strlen(MenuStr[0])>ScreenWidth) + tempx=ScreenWidth-strlen(MenuStr[0]); + + MouseHide(); + if (ItemOn) + { + sx=tempx; + sy=ItemOn; + print(MenuStr[ItemOn-1]); + } + + xormask=0xffff; + ItemOn=newitem; + strncpy(tempstr,&MenuStr[ItemOn-1][1],strlen(MenuStr[ItemOn-1])-2); + sx=tempx+1; + sy=ItemOn; + print(tempstr); + xormask=0; + + MouseShow(); +} + + + +///////////////////////////////////////////////////////////////// +// +// See if a menu was closed +// +///////////////////////////////////////////////////////////////// +void HandleCloseMenu(void (*UserRoutine)(void)) +{ + MenuDef *items; + int loop,tempx; + char tempstr[80]=""; + + if (!OpenMenu) + { + UserRoutine(); + return; + } + + if (ItemOn) + { + items=(MBarPtr+OpenMenu-1)->menu_def; + tempx=MenuInfo[OpenMenu-1].menux; + if (tempx+strlen(MenuStr[0])>ScreenWidth) + tempx=ScreenWidth-strlen(MenuStr[0]); + + for (loop=0;looproutine; + } + + OpenMenu=0; + RestoreBackground(); +} + + +///////////////////////////////////////////////////////////////// +// +// Save the background +// +///////////////////////////////////////////////////////////////// +void SaveBackground(int x,int y,int w,int h) +{ + long size; + unsigned loc,loop,loop1,seg,planelen; + + Back[WhichBack].savex=x; + Back[WhichBack].savey=y; + Back[WhichBack].savew=w; + Back[WhichBack].saveh=h; + + MouseHide(); + switch (videomode) + { + case CGA: + MMAllocate(&Background[WhichBack],(w/4)*h); + + for(loop=y;loopnum_items && !flag) + { + int len,max_width,loop; + MenuDef *the_item; + char string[80]; + + // + // First, determine xcoord & namewidth & print + // + + strcpy(string,(MBarPtr+count)->menu_name); + len=strlen(string); + MenuInfo[NumMenus].menux=sx; + MenuInfo[NumMenus].menunamelen=len+2; + if (len+sx>ScreenWidth-1) + { + string[ScreenWidth-1-sx]=0; + MenuInfo[NumMenus].menunamelen=ScreenWidth-1-sx; + MenuInfo[NumMenus].menux=ScreenWidth-MenuInfo[NumMenus].menunamelen; + flag++; + } + + drawchar(sx++,sy,' '); + print(string); + drawchar(sx++,sy,' '); + + // + // Now, figure out length of widest item + // + + max_width=0; + the_item=(MBarPtr+count)->menu_def; + + for (loop=0;loop<(MBarPtr+count)->num_items;loop++) + { + int len; + + len=strlen((the_item+loop)->item_name); + if (len>max_width) + max_width=len; + } + + MenuInfo[NumMenus].menuwidth=max_width+1; + + count++; + NumMenus++; + } + + // + // clear bottom line of menubar + // + switch(videomode) + { + case CGA: + { + unsigned huge *CGAmem=MK_FP(0xb800,240+0x2000); + for(i=0;i<40;i++) + *(CGAmem+i)=0; + } + break; + case EGA1: + case EGA2: + { + char huge *EGAmem=MK_FP(0xa000,0); + outport(GCindex,GCmode); + outport(SCindex,0x0f00 | SCmapmask); + for (i=0;i=0x3b && sc<=0x44) + { + char str[3]; + strcpy(tempstr,"F"); + itoa (sc-0x3a,str,10); + strcat(tempstr,str); + } + else if (sc==0x57) + strcpy(tempstr,"F11"); + else if (sc==0x59) + strcpy(tempstr,"F12"); + else if (sc==0x46) + strcpy(tempstr,"SCRLLK"); + else if (sc==0x1c) + strcpy(tempstr,"ENTER"); + else if (sc==0x36) + strcpy(tempstr,"RSHIFT"); + else if (sc==0x37) + strcpy(tempstr,"PRTSC"); + else if (sc==0x38) + strcpy(tempstr,"ALT"); + else if (sc==0x47) + strcpy(tempstr,"HOME"); + else if (sc==0x49) + strcpy(tempstr,"PGUP"); + else if (sc==0x4f) + strcpy(tempstr,"END"); + else if (sc==0x51) + strcpy(tempstr,"PGDN"); + else if (sc==0x52) + strcpy(tempstr,"INS"); + else if (sc==0x53) + strcpy(tempstr,"DEL"); + else if (sc==0x45) + strcpy(tempstr,"NUMLK"); + else + { + smallstr[0]=chartable[sc]; + smallstr[1]=0; + strcpy(tempstr,smallstr); + } + + return tempstr; +} + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +// +// +// DIALOG MANAGER CODE +// +// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// +// +// Dialog Boxes! +// +///////////////////////////////////////////////////////// +int DoDialog(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + MouseHide(); + SaveBackground((screencenterx-TheDialog->width/2)*8, + (screencentery-TheDialog->height/2)*8,(TheDialog->width+2)*8, + (TheDialog->height+2)*8); + + xormask=0; + centerwindow(TheDialog->width,TheDialog->height); + ox=sx; + oy=sy; + print(TheDialog->text); + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=sx=ox+(TheButton+i)->xoff; + yc[i]=sy=oy+(TheButton+i)->yoff; + xx=sx-1; + yy=sy-1; + print((TheButton+i)->text); + wid[i]=strlen((TheButton+i)->text); + + if ((TheButton+i)->border) + DrawBorder(xx,yy,wid[i]+1,2,(TheButton+i)->border); + } + + if (TheDialog->hook) + { + HookRoutine=(void (*)(int x,int y))TheDialog->hook; + HookRoutine(ox,oy); + } + MouseShow(); + + clearkeys(); + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + + RestoreBackground(); + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just CHECK a Dialog Box's BUTTONS +// +///////////////////////////////////////////////////////// +int CheckButtons(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + ox=screencenterx-TheDialog->width/2+1; + oy=screencentery-TheDialog->height/2+1; + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=ox+(TheButton+i)->xoff; + yc[i]=oy+(TheButton+i)->yoff; + wid[i]=strlen((TheButton+i)->text); + } + + + clearkeys(); + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + clearkeys(); + + if (Clicked) + { + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + } + + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just CHECK a Dialog Box's BUTTONS +// BUT!...RETURN IF MOUSE BUTTON IS PRESSED OUTSIDE DIALOG BUTTON! +// +///////////////////////////////////////////////////////// +int CheckButtonsRet(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + ox=screencenterx-TheDialog->width/2+1; + oy=screencentery-TheDialog->height/2+1; + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=ox+(TheButton+i)->xoff; + yc[i]=oy+(TheButton+i)->yoff; + wid[i]=strlen((TheButton+i)->text); + } + + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + if (MouseButton()&2) + return -1; + + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + // + // arrows or PgUp/PgDn/Home/End + // + if (keydown[0x48] || keydown[0x50] || keydown[0x4b] || keydown[0x4d] || + keydown[0x49] || keydown[0x51] || keydown[0x47] || keydown[0x4f] || + keydown[0x39] || keydown[0x2e]) + return -1; + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + + if (!Clicked) // MOD TO ORIGINAL CHECKBUTTONS + return -1; + + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + clearkeys(); + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just DRAW a Dialog Box +// +///////////////////////////////////////////////////////// +void DrawDialog(DialogDef *TheDialog,int saveback) +{ + btype *TheButton; + int i,ox,oy,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + MouseHide(); + if (saveback) + SaveBackground((screencenterx-TheDialog->width/2)*8, + (screencentery-TheDialog->height/2)*8,(TheDialog->width+2)*8, + (TheDialog->height+2)*8); + + xormask=0; + centerwindow(TheDialog->width,TheDialog->height); + ox=sx; + oy=sy; + print(TheDialog->text); + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=sx=ox+(TheButton+i)->xoff; + yc[i]=sy=oy+(TheButton+i)->yoff; + xx=sx-1; + yy=sy-1; + print((TheButton+i)->text); + wid[i]=strlen((TheButton+i)->text); + + if ((TheButton+i)->border) + DrawBorder(xx,yy,wid[i]+1,2,(TheButton+i)->border); + } + + if (TheDialog->hook) + { + HookRoutine=(void (*)(int x,int y))TheDialog->hook; + HookRoutine(ox,oy); + } + + MouseShow(); +} + + +///////////////////////////////////////////////////////// +// +// Error Dialog Box +// +///////////////////////////////////////////////////////// +char errstring[200],bstring[20]; +btype ERROKb={bstring,0,0,2}; +DialogDef ERRR={errstring,0,0,1,&ERROKb,NULL}; + +void ErrDialog(char *string,char *bstr) +{ + int maxw=0,width=0,height=1,i; + + if (strlen(string)>200) + Quit("Programmer Error: ErrDialog string is too long!"); + + for (i=0;imaxw) + maxw=width; + + if (string[i]=='\n') + { + height++; + width=0; + } + } + height+=3; // add for button! + + if (strlen(bstr)>maxw) + Quit("Programmer Error: ErrDialog BUTTONstring is longer than dialog!"); + + strcpy(bstring,bstr); + strcpy(errstring,string); + ERRR.width=maxw; + ERRR.height=height; + ERRR.numbuttons=1; + if (!bstr[0]) + { + ERRR.numbuttons=0; + ERRR.height-=3; + } + + ERROKb.xoff=(maxw/2)-(strlen(bstr)/2); + ERROKb.yoff=height-2; + + if (bstr[0]) + DoDialog(&ERRR); + else + DrawDialog(&ERRR,1); +} + + +///////////////////////////////////////////////////////// +// +// Draw a border +// +///////////////////////////////////////////////////////// +void DrawBorder(int x,int y,int w,int h,int b) +{ + int xx=x,yy=y,j; + + if (b==2) + { + drawchar(xx,yy,15); + drawchar(xx+w,yy,17); + drawchar(xx,yy+h,20); + drawchar(xx+w,yy+h,22); + + for (j=yy+1;jbuttons; + + *x=(TheButton+button)->xoff+screencenterx-TheDialog->width/2+1; + *y=(TheButton+button)->yoff+screencentery-TheDialog->height/2+1; +} + + +///////////////////////////////////////////////////////// +// +// Get the XY coords of a dialog +// +///////////////////////////////////////////////////////// +void GetDialogXY(DialogDef *TheDialog,unsigned *x,unsigned *y) +{ + *x=screencenterx-TheDialog->width/2+1; + *y=screencentery-TheDialog->height/2+1; +} + + +//////////////////////////////////////////////////// +// +// Allow user to select a list item (like the menus) +// +//////////////////////////////////////////////////// +int CheckList(int x,int y,int w,int h,void (*oncode)(),void (*offcode)(),int blink) +{ + enum {upup,updown,downup,downdown} clicks; + static char bpress=0; + unsigned mx,my,i; + int high=-1; + + + while(1) + { + MouseCoords(&(int)mx,&(int)my); + mx/=8; + my/=8; + bpress=((bpress<<1)|(MouseButton()&1))&3; + switch(bpress) + { + case upup: + return -1; + case updown: + if (mx>=x && mx=y && my=x && mx=y && my200) + Quit("Programmer Error: Message string is too long!"); + + for (i=0;imaxw) + maxw=width; + + if (string[i]=='\n') + { + height++; + width=0; + } + } + height+=3; // add for buttons! + + strcpy(MessStr,string); + Mess.width=maxw; + Mess.height=height; + + MessOKb[1].xoff=(maxw/4)-(strlen(MessOKb[0].text)/2); + MessOKb[1].yoff=height-2; + MessOKb[0].xoff=(maxw/4)*3-(strlen(MessOKb[1].text)/2); + MessOKb[0].yoff=height-2; + + return DoDialog(&Mess); +} + + +///////////////////////////////////////////////// +// +// GetPath dialog +// *path is returned +// (exit:0 if OK,-1 if Not Successful,-2 if Canceled) +// +///////////////////////////////////////////////// +#define LISTX 1 +#define LISTY 3 + +char dstr[80]; +btype GPb={"Cancel",15,3,1}; +DialogDef GPd={dstr,22,14,1,&GPb,NULL}; +char NameList[MAXFDNAMES][13]; +int base; +struct ffblk f; + +int GetPath(char *string,char *filter,char *path) +{ + char pname[64]; + unsigned int numnames=0,max,dx,dy,redraw,exit; + int select,zset,i; + + + strcpy(pname,filter); + for (zset=0,i=strlen(pname);i>=0;i--) + if (pname[i]=='\\') + { + pname[i+1]=0; + zset++; + break; + } + if (!zset) + pname[0]=0; + + strcpy(dstr,string); + // + // FIRST, GET THE NAMES FROM THE DIRECTORY + // + if (findfirst(filter,&f,FA_ARCH)) + return -1; + strcpy(NameList[numnames++],f.ff_name); + + while(!findnext(&f) && numnames=0) + { + redraw=exit=1; + continue; + } + + GetButtonXY(&GPd,0,&sx,&sy); + select=CheckList(sx,sy,strlen(GPb.text),1,CancelOn,CancelOff,0); + if (!select || keydown[1]) + { + RestoreBackground(); + while(keydown[1]); + clearkeys(); + return -2; + } + + // + // CHECK ARROWS & PGUP/DN + // + if (keydown[0x48] && base) + { + base--; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x48]); + } + else + if (keydown[0x50] && base+10numnames) + base=numnames-10; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x51]); + } + + } while(!redraw); + } while(!exit); + + // + // RETURN PATHNAME + // + RestoreBackground(); + strcpy(path,pname); + strcat(path,NameList[select+base]); + findfirst(path,&f,FA_ARCH); + return 0; +} + + +static void FDon(int x,int y,int w) +{ + xormask=1; + FDoff(x,y,w); + xormask=0; +} + +static void FDoff(int x,int y,int w) +{ + MouseHide(); + sx=x; + sy=y; + print(NameList[w+base]); + MouseShow(); +} + + +static void CancelOn(int x,int y) +{ + xormask=1; + CancelOff(x,y); + xormask=0; +} + +static void CancelOff(int x,int y) +{ + MouseHide(); + sx=x; + sy=y; + print("Cancel"); + MouseShow(); +} + + +///////////////////////////////////////////////// +// +// GetList dialog +// Fill "NameList[?][13]" with your strings +// (exit:>=0 is selection,-1 if Not Successful,-2 if Canceled) +// +///////////////////////////////////////////////// +int GetList(char *string,int numnames) +{ + unsigned int max,dx,dy,redraw,exit,i; + int select; + + + strcpy(dstr,string); + + DrawDialog(&GPd,1); + MouseHide(); + GetDialogXY(&GPd,&dx,&dy); + DrawBorder(dx+LISTX-1,dy+LISTY-1,13,11,1); + MouseShow(); + + base=exit=0; + + // + // THIS LOOP DRAWS THE DIALOG + // + do + { + redraw=0; + MouseHide(); + max=10; + if (numnames<10) + max=numnames; + for (i=0;i=0) + { + redraw=exit=1; + continue; + } + + GetButtonXY(&GPd,0,&sx,&sy); + select=CheckList(sx,sy,strlen(GPb.text),1,CancelOn,CancelOff,0); + if (!select || keydown[1]) + { + RestoreBackground(); + while(keydown[1]); + clearkeys(); + return -2; + } + + // + // CHECK ARROWS & PGUP/DN + // + if (keydown[0x48] && base) + { + base--; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x48]); + } + else + if (keydown[0x50] && base+10numnames) + base=numnames-10; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x51]); + } + + } while(!redraw); + } while(!exit); + + // + // RETURN SELECTION + // + RestoreBackground(); + return select+base; +}