koreth@ssyx.ucsc.edu (Steven Grimm) (06/23/88)
Submitted-by: ucbvax!ihnp4!stag!trb (Todd Burkey) Posting-number: Volume 1, Issue 59 Archive-name: readme12 The following is the source code and executable for a README application that implements my new POPHELP mechanism. Full source code is included for README (MW C) and it runs in both Medium Res (RGB) and High Res (mono). A menu configuration file that describes POPHELP is also included (and automatically presented to the user when they run README.PRG). The program is self documenting (it would be silly if it wasn't). My primary goal in writing the POPHELP routines was to beef up HDSCAN's interactive help and to lay the groundwork for full popup menu control for users of HDSCAN. It ended up to be such short and simple code that I decided to put it out for others to use, add to their own programs, or simply learn some coding techniques from. The code has been implemented in the next version of HDSCAN (took about 2 hours to integrate it) and does tend to snaz up your application some. One of the local developers has even created a README pophelp configuration file for Mark Johnson C. Enjoy. Some features of POPHELP: 1) External Help file driven (think of it as a help resource file). Can also be fully integrated into the application code. 2) Allows context sensitive help applications to be easily written. 3) Users can wander through the help popups via arrow keys or the mouse. 4) The popups are very fast and consist of selectable and non-selectable text in shadowed popup boxes. 5) The implementor can vary screen color from popup to popup. 6) External files can be 'fed' into a popup menu (saving on memory for little used/accessed help topics). Some features of README: 1) Originally intended as a test vehicle for checking out the POPHELP routines, I actually am using README to replace my README files for HDSCAN and DISKSCAN. Much cleaner user interface. 2) Allows a user defined 'front page' from which the HELP key can be pressed to allow a user to 'learn' about an application in a logical fashion. -Todd Burkey "A member of STdNET - The ST developers' Network" trb@stag.UUCP ------------------------------------------------------------- #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # README12.C # MENU.TRB # README.TRB # SAMPLE.TXT # sed 's/^X//' << 'SHAR_EOF' > README12.C && X /* README.PRG Vers. 1.0 By Todd Burkey, 6/1/88. */ X/* Version 1.1 6/10/88-Todd Burkey: Added Color selection and Tab support */ X/* Version 1.2 6/19/88-Todd Burkey: Started code setup for menu overlays */ X X/* The source code and accompany text files (MENU.TRB and README.TRB) must X always accompany the README.PRG file (ARC'ed as a package). */ X X/* X This program shows one use of the POPHELP mechanism (Copyright 1988 by X Todd Burkey). POPHELP is intended to be a 'clean' way of presenting help X to users of a program and was also written to demonstrate in source code X how to do those confusing linea/vdi/etc things that all of our manuals kind X of gloss over. I am not saying that my methods are proper coding or even X close, but at least it works. In order to ensure that this code and the X techniques involved stay accessible to the public at large, I have to make X the following stipulations: X X 1) This program and source code may be freely distributed as long as no X profits are made in the process (Club Disks of the Month and BBS's are X excepted, of course.) X 2) All derivatives of the routines in this code must include this notice X verbatim and are similarly subject to the conditions in 1, above. X 3) No warrantees are made as to the usefulness or safety of using this X code. The user uses it at his/her own risk. X X -Todd Burkey "A member of STdNET-The ST developers' Network" X trb@stag.UUCP X 3546 Pilgrim Lane X Plymouth, MN 55441 X*/ X X#include <linea.h> X#include <ctype.h> X#include <stdio.h> X#include <aesbind.h> X#include <osbind.h> X#include <vdibind.h> X#include <bios.h> X X#define RESTORE 1 X#define SAVE 2 X#define ONLYTEXT 1 X#define MOREHELP 2 X#define ESC 27 X#define HELP 98 X#define UPARROW 72 X#define DOWNARROW 80 X#define LEFTARROW 75 X#define RIGHTARROW 77 X#define LEFTBUTTON 0x740000L X#define RIGHTBUTTON 0x750000L X#define MAX_MENUS 100 X X/* and now some necessary vdi/aes stuff */ Xint h,xy[16],contrl[12],intin[128],ptsin[128],intout[128],ptsout[128]; Xint src[11]; Xint scr_a[] = { 0, 0, 640, 200, 40, 0, 2, 0, 0, 0 }; Xchar *oldscr,*newscr,*memblk; X X/* and now for the POPMENU related arrays */ Xint menu_col[MAX_MENUS+1], /* upper left column number for menu */ X menu_row[MAX_MENUS+1], /* upper left row number for menu */ X menu_fr[MAX_MENUS], /* first character in menu_s for the menu */ X menu_to[MAX_MENUS], /* last character in menu_s for the menu */ X menu_last[MAX_MENUS], /* previous menu that you viewed */ X on_line[MAX_MENUS], /* what line were you last on? */ X menu_rgb[MAX_MENUS+1][4]; /* color rgb map for menu */ Xchar menu_s[30000]; Xint error_cnt=0; Xint which; /* which menu are we on */ Xint menu_length, /* length (height) of current menu */ X menu_width, /* width of current menu */ X lc1,lc2,lr1,lr2, /* last corners (col/row) of menu box */ X menu_ptr[24], /* a menu selections' next menu (forward ptr) */ X menu_type[24]; /* type of menu entry...ONLYTEXT or MOREHELP */ Xchar menu_line[24][130]; /* what you see in the box */ Xchar help_path[100]; /* tbd...for global path lookup... */ Xint menu_s_pos; /* tbd...useful if we use menu overlays */ X X/* and some stuff I need */ Xlong tst,vtst; Xint htst,mono,black,blue,red,green; Xint save_col[4]; Xlong _stksize = 40000L; Xstatic long patmsk = -1; X Xmain() X{ X int i; X color_init(); X ws_init(); /* do all that messy vdi/linea initialization */ X build_help(); /* build the internal help arrays from menu.trb */ X if(Bconstat(BC_KBD)) Bconout(BC_KBD,0x0a); /* set mouse cursor mode */ X if(Bconstat(BC_KBD)) Bconout(BC_KBD,0x14); /* 20 pulses per x move */ X if(Bconstat(BC_KBD)) Bconout(BC_KBD,0x05); /* 5 pulses per y move */ X mon_keys(); X if(Bconstat(BC_KBD)) Bconout(BC_KBD,0x08); /* reset mouse mode to normal */ X for(i=0;i<4;i++) Setcolor(i,save_col[i]); X } X Xcolor_init() /* check resolutions and setup accordingly */ X{ X int i; X i=Getrez(); X if(i==0) { X printf("Sorry, Medium or High Res only\n[Hit any key]\n"); X Crawcin(); X exit(1); X } X if(i==2) { X mono=1; X black='3'; X blue='3'; X red='3'; X green='0'; X } X else { X mono=0; X black='2'; X blue='0'; X red='1'; X green='2'; X } X for(i=0;i<4;i++) save_col[i]=Setcolor(i,-1); X for(i=0;i<=MAX_MENUS;i++) { /* setup default colors */ X if(mono) menu_rgb[i][0]=0x777; X else menu_rgb[i][0]=0x006; X menu_rgb[i][1]=0x600; X menu_rgb[i][2]=0x000; X if(mono) menu_rgb[i][3]=0x000; X else menu_rgb[i][3]=0x775; X } X set_rgb(0); X } X Xmon_keys() /* simple loop that waits for a HELP key or Q key */ X{ X while(((tst=Bconin(2))&0xFF)!='Q') { X tst=tst>>16; X if(tst==HELP) { X which=0; X show_help(1); X } X while((Cconis())!=0) Crawcin(); X } X v_clsvwk(h); X appl_exit(); X } X Xset_rgb(m) Xint m; X{ X Setcolor(0,menu_rgb[m][0]); X Setcolor(1,menu_rgb[m][1]); X Setcolor(2,menu_rgb[m][2]); X Setcolor(3,menu_rgb[m][3]); X } X Xdraw_help(menu) /* draw the selected help popup */ Xint menu; X{ X int i,j; X/* First, gather up all of the info for the CURRENT menu to draw */ X menu_length=0; X if(menu>=MAX_MENUS||menu<0) X sprintf(menu_line[menu_length++],"ERROR IN MENU.TRB. Menu numbers must be between 0 and 99."); X else if(menu_fr[menu]<0) X sprintf(menu_line[menu_length++],"ERROR IN MENU.TRB. Can't Find the menu definition for %d.",menu); X if(menu_length>0) { X sprintf(menu_line[menu_length++],"Please fix this problem ASAP. Press the Left Arrow now."); X menu_width=strlen(menu_line[0]); X menu_type[0]=menu_type[1]=ONLYTEXT; X menu=MAX_MENUS; X menu_col[menu]=4; X menu_row[menu]=11; X } X else if(menu_s[menu_fr[menu]]!='<') { X for(i=menu_fr[menu],j=0,menu_width=0;i<=menu_to[menu];i++) { X if(menu_s[i]=='\0') { X menu_line[menu_length++][j-1]='\0'; X j++; X if(j>menu_width) menu_width=j; X j=0; X } X else { X if(j==0&&menu_s[i]=='+') menu_type[menu_length]=MOREHELP; X else if(j==0&&menu_s[i]=='T') menu_type[menu_length]=ONLYTEXT; X else if(j==0&&menu_s[i]=='=') { X menu_ptr[menu_length-1]=atoi(&menu_s[i+2]); X while(menu_s[i]!='\0'&&i<10000) i++; X j=0; X } X else if(j<=1&&menu_s[i]==':') j++; X else { X menu_line[menu_length][j-1]=menu_s[i]; X j++; X } X } X } X menu_width=menu_width-2; X } X else viewfile(menu); X set_rgb(menu); X lc1=menu_col[menu]; X lr1=menu_row[menu]; X lc2=lc1+menu_width; X lr2=lr1+menu_length; X/* Now, save the part of the screen that we are gonna draw on. */ X screen_it(SAVE,lc1,lr1,lc2,lr2); X/* and draw the popup */ X fboxcr(lc1,lr1,lc2,lr2); X boxcr(lc1,lr1,lc2,lr2); X for(i=0;i<menu_length;i++) { X if(menu_type[i]==ONLYTEXT) { X if(mono) printcr(lc1,lr1+i,menu_line[i]); /* modify for slant someday */ X else tprintcr(lc1,lr1+i,menu_line[i]); X } X else { X if(mono) printcr(lc1,lr1+i,menu_line[i]); X else bprintcr(lc1,lr1+i,menu_line[i]); X } X } X } X Xerase_help() /* move the stuff we saved to the scratch pad back */ X{ X screen_it(RESTORE,lc1,lr1,lc2,lr2); X } X Xhilite_menu(i) /* highlight the selection under the cursor */ Xint i; X{ X if(mono) { X printcr(lc1,lr1+on_line[which],menu_line[on_line[which]]); X bprintcr(lc1,lr1+i,menu_line[i]); X } X else { X bprintcr(lc1,lr1+on_line[which],menu_line[on_line[which]]); X printcr(lc1,lr1+i,menu_line[i]); X } X on_line[which]=i; X } X Xshow_help(menu) /* recursive routine handling the help popup walking */ Xint menu; X{ X int i,all_text; X if(which<0) return; X draw_help(menu); X on_line[which]=0; X for(i=0;i<menu_length&&menu_type[i]==ONLYTEXT;i++); X if(i<menu_length) { X all_text=0; X on_line[which]=i; X if(mono) bprintcr(lc1,lr1+i,menu_line[i]); X else printcr(lc1,lr1+i,menu_line[i]); X } X else all_text=1; X while(((tst=Bconin(2))&0xFF)!=ESC) { X htst=tst&0xFF; X vtst=tst>>16; X if(!all_text&&which<100&&(tst==RIGHTBUTTON||vtst==RIGHTARROW)) { X erase_help(); X menu_last[which++]=menu; X show_help(menu_ptr[on_line[which-1]]); X if(which<0) return; X continue; X } X else if(which>0&&(tst==LEFTBUTTON||vtst==LEFTARROW)) { X if(menu>=0) { X erase_help(); X menu=menu_last[--which]; X draw_help(menu); X if(menu_type[on_line[which]]!=ONLYTEXT) X if(mono) bprintcr(lc1,lr1+on_line[which],menu_line[on_line[which]]); X else printcr(lc1,lr1+on_line[which],menu_line[on_line[which]]); X return; X } X } X else if(on_line[which]<menu_length&&(vtst==DOWNARROW||htst=='j')) { X for(i=on_line[which]+1;i<menu_length&&menu_type[i]==ONLYTEXT;i++); X if(i<menu_length) hilite_menu(i); X } X else if(on_line[which]>0&&(vtst==UPARROW||htst=='k')) { X for(i=on_line[which]-1;i>0&&menu_type[i]==ONLYTEXT;i--); X if(menu_type[i]!=ONLYTEXT) hilite_menu(i); X } X else { X if(menu!=0&&vtst!=UPARROW&&vtst!=DOWNARROW&&vtst!=LEFTARROW&&vtst!=RIGHTARROW) X error_cnt++; X if(error_cnt>1||vtst==HELP) { X erase_help(); X error_cnt=0; X menu_last[which++]=menu; X show_help(0); X if(which<0) return; X continue; X } X } X while((Cconis())!=0) Crawcin(); X } X erase_help(); X which= -1; X } X Xpop_read(s) /* This routine reads a menu file and builds the internal tree */ Xchar *s; X{ X char buf[128]; X FILE *ifp; X int i,j,x,y,r,g,b,on_menu; X if((ifp=fopen(s,"r"))==NULL) { X printf("menu configuration file:%s was not found!\n",s); X exit(99); X } X j=menu_s_pos; /* pointer into menu_s array */ X if(ifp!=NULL) { X while(fgets(buf,128,ifp)!=NULL) { X if(buf[1]!=':') continue; X switch(buf[0]) { X case '<': X case 'T': X case '+': X case '=': X for(i=0;i<strlen(buf);i++) X if(buf[i]!='\t') menu_s[j++]=buf[i]; X else { X x=expand_tab(j); X for(y=j;y<x;y++) menu_s[j++]=' '; X } X menu_s[j-1]='\0'; X break; X case '#': X if(j>0) menu_to[on_menu]=j-1; X on_menu=atoi(&buf[2]); X if(on_menu>MAX_MENUS) { X printf("ERROR. Can't define menu. Its' number [%d] is >100...aborting\n",on_menu); X exit(1); X } X menu_fr[on_menu]=j; X break; X case 'X': X menu_col[on_menu]=atoi(&buf[2]); X break; X case 'Y': X menu_row[on_menu]=atoi(&buf[2]); X break; X case '0': X case '1': X case '2': X case '3': X if(strlen(buf)<6) printf("ERROR. RGB menu definition too short: %s\n",buf); X r=buf[2]-'0'; X g=buf[3]-'0'; X b=buf[4]-'0'; X if(r<0||r>7||g<0||g>7||b<0||b>7) X printf("ERROR. RGB values incorrect (must be 0-7): %s\n",buf); X if(on_menu==1) X for(i=1;i<=MAX_MENUS;i++) menu_rgb[i][buf[0]-'0']=r*256+g*16+b; X else menu_rgb[on_menu][buf[0]-'0']=r*256+g*16+b; X break; X } X } X if(j>0) menu_to[on_menu]=j-1; X fclose(ifp); X } X } X Xbuild_help() /* this routine reads the menu file and builds the popup tree */ X{ X int i; X for(i=0;i<MAX_MENUS;i++) menu_fr[i]= -1; X menu_s_pos=0; /* pointer into menu_s array */ X pop_read("MENU.TRB"); X } X Xviewfile(menu) /* gather menu information from a file */ Xint menu; /* would be nice to modify this to allow paging... :-) */ X{ /* Note that we build a fake menu structure from the file */ X int i,j,x,y; X char ebuf[150],buf[129],s[200]; X FILE *ifp; X strcpy(s,&menu_s[menu_fr[menu]+2]); X if ((ifp=fopen(s,"r"))==NULL) { /* throw up a read-only one-liner */ X sprintf(menu_line[0],"Sorry, can't open %s. Press the left arrow.",s); X menu_length=1; X menu_width=strlen(menu_line[0]); X menu_type[0]=ONLYTEXT; X return; X } X menu_length=0; X menu_width=0; X while((menu_length+menu_row[menu])<24&&fgets(buf,128,ifp)!=NULL) { X j=0; X for(i=0;i<strlen(buf);i++) X if(buf[i]!='\t') ebuf[j++]=buf[i]; X else { X x=expand_tab(j); X for(y=j;y<x;y++) ebuf[j++]=' '; X } X ebuf[j-1]='\0'; X strcpy(menu_line[menu_length],ebuf); X menu_type[menu_length++]=ONLYTEXT; X if(j>menu_width) menu_width=j; X } X fclose(ifp); X } X Xws_init() X{ X int ii,i,work_in[11],work_out[57]; X linea0(); /* yep, we are going to try linea stuff */ X src[0]=0;src[1]=0; /* general setup for doing vdi stuff follows*/ X work_in[0]=1; X for(i=1;i<10;i++) work_in[i]=1; X work_in[10]=2; X appl_init(); X h=graf_handle(&ii,&ii,&ii,&ii); X graf_mouse(256,NULL); X clear_screen(); X v_opnvwk(work_in,&h,work_out); X src[2]=work_out[0]+1; X src[3]=work_out[1]+1; X src[4]=src[2]>>4; X src[5]=0; X if(mono) src[6]=1; X else src[6]=2; X if(mono) { /* modify fdb for the vro_cpyfm */ X scr_a[3]=400; /* 400 pixels high */ X scr_a[6]=1; /* 1 bit plane */ X } X memblk=(char *)Malloc(32*1024L); /* alloc 32k */ X oldscr=(char *) Physbase(); /* where is screen */ X newscr=(char *) (((long) memblk+0xFFL)& ~(0xFFL)); /* assign paste */ X *((long *)src)=(long) oldscr; /* assign ptr to screen */ X *((long *)scr_a)=(long) newscr; /* assign ptr to paste */ X v_hide_c(h); X draw_cover(); X } X Xclear_screen() X{ X v_clrwk(h); X } X Xdraw_cover() /* display a setup (cover) page */ X{ X char buf[129]; X FILE *ifp; X int i; X i=0; X clear_screen(); X if((ifp=fopen("README.TRB","r"))==NULL) X printf("README.TRB not found! If MENU.TRB exists, press HELP for more info.\n"); X else { X printf("\33f\33Y%c%c\33pReady? Press The HELP key for more info, then ESC and Q to quit\33q",56,42); X while(fgets(buf,128,ifp)!=NULL&&i<24) { X if(buf[0]=='/') continue; X if(i==0) printf("\33Y %s",buf); X else printf("%s",buf); X i++; X } X fclose(ifp); X } X } X Xtprintcr(c,r,string) /* print a red string at <col,row> */ Xint c,r; Xchar *string; X{ X r=r+32; X c=c+32; X printf("\33Y%c%c\33c%c\33p%s\33q\33c%c\n",r,c,red,string,blue); X } X Xbprintcr(c,r,string) /* print a 'bold/reverse video' string at <col,row> */ Xint c,r; Xchar *string; X{ X r=r+32; X c=c+32; X printf("\33Y%c%c\33p%s\33q\n",r,c,string); X } X Xprintcr(c,r,string) /* print a string at <column,row> */ Xint c,r; Xchar *string; X{ X r=r+32; X c=c+32; X printf("\33Y%c%c%s\n",r,c,string); X } X Xfboxcr(c1,r1,c2,r2) /* draw a shadow box and then an overlay one. */ Xint c1,r1,c2,r2; /* using linea for the fun of it */ X{ X LNMASK= -1; X WMODE= 0; X CLIP=0; X PATPTR=&patmsk; X PATMSK=1; X if(mono) COLBIT0=1; X else { X COLBIT0=0; X COLBIT1=1; X } X X1=(c1<<3)+5; X X2=(c2<<3)+7; X if(mono) { X Y1=(r1<<4)-10; X Y2=(r2<<4)-6; X } X else { X Y1=(r1<<3)-5; X Y2=(r2<<3)-3; X } X linea5(); /* lot of work for a stupid rectangle, but this shows linea */ X if(mono) COLBIT0=0; X else COLBIT0=1; X X1=(c1<<3)-2; X X2=(c2<<3); X if(mono) { X Y1=(r1<<4)-2; X Y2=(r2<<4); X } X else { X Y1=(r1<<3)-1; X Y2=(r2<<3); X } X linea5(); X boxcr(c1,r1,c2,r2); X } X Xboxcr(c1,r1,c2,r2) /* now draw a hollow box around the top filled...*/ Xint c1,r1,c2,r2; X{ X xy[0]=xy[6]=xy[8]=(c1<<3)-3; X xy[2]=xy[4]=(c2<<3)+1; X if(mono==1) { X xy[1]=xy[3]=xy[9]=(r1<<4)-3; X xy[5]=xy[7]=(r2<<4)+1; X } X else { X xy[1]=xy[3]=xy[9]=(r1<<3)-2; X xy[5]=xy[7]=(r2<<3)+1; X } X v_pline(h,5,xy); X } X Xscreen_it(wh,c1,r1,c2,r2) /* do a simple blit to or from the paste */ Xint wh,c1,r1,c2,r2; /* columns and rows in cursor coordinates */ X{ X int lx,ux,ly,uy; X lx=(c1<<3)-4; X ux=(c2<<3)+7; X if(mono==1) { X ly=(r1<<4) - 16; X uy=(r2<<4)+4; X if(uy>399) uy=399; X } X else { X ly=(r1<<3) - 8; X uy=(r2<<3)+2; X if(uy>199) uy=199; X } X if(lx<0) lx=0; X if(ly<0) ly=0; X if(ux>639) ux=639; X xy[1]=xy[5]=ly; /* uly */ X xy[3]=xy[7]=uy; /* lry */ X xy[0]=xy[4]=lx; /* ulx */ X xy[2]=xy[6]=ux; /* lrx */ X if(wh==SAVE) X vro_cpyfm(h,3,xy,src,scr_a); X else X vro_cpyfm(h,3,xy,scr_a,src); X } X Xint expand_tab(index) /* expand a tab out, calculating new position */ Xint index; X{ X do X index++; X while ((index&0x07)!=0); X return(index); X } X SHAR_EOF chmod 0600 README12.C || echo "restore of README12.C fails" sed 's/^X//' << 'SHAR_EOF' > MENU.TRB && X* SAMPLE MENU TREE FOR POPHELP (Todd Burkey/5-30-88) */ X/* menu for level 0 help */ X#:0 XX:20 XY:2 XT: POPHELP By Todd Burkey XT: XT:Uh-oh. You need HELP for POPHELP? XT:OK, the first thing to remember is XT:that in POPHELP, you really only XT:need to use the four arrow keys XT:and the ESC key. The up and down XT:arrows will move you up and down in XT:the current pop-up...but only when XT:there is selectable (blue) text in XT:the popup. Note that this popup has XT:NO selectable text...you can just XT:read it and exit. Which brings us XT:to the left and right arrow keys. XT:The right key gets you into a menu, XT:while the left key moves you back XT:out of a menu. The ESC key? It gets XT:you out of the popups altogether. XT:You can press the LEFT ARROW now. X#:1 XX:5 XY:15 XT:WELCOME TO POPHELP X+:HELP ON POPHELP X=:3 X+:POPHELP MANIFESTO X=:40 X+:Who made this mess X=:41 X+:ABOUT README X=:50 X+:Some Error Testing X=:42 X+:Other menu #4 X=:4 X+:Other Menu #6 X=:6 X X#:50 XX:4 XY:4 X1:530 XT:README is a generic application that I hope you find useful in setting XT:up useful on-line documentation for programs you develop. Feel free to XT:give out copies of README to others who are learning C or who you feel XT:could use a better help mechanism. I will try to keep the pophelp file XT:formats upwards compatible, so keep your eyes open for future releases XT:of improved versions of this program. X X#:40 XX:2 XY:4 XT:This program shows one use of the POPHELP mechanism (Copyright 1988 by XT:Todd Burkey). POPHELP is intended to be a 'clean' way of presenting help XT:to users of a program and was also written to demonstrate in source code XT:how to do those confusing linea/vdi/etc things that all of our books kind XT:of gloss over. I am not saying that my methods are proper coding or even XT:close, but at least it works. In order to ensure that this code and the XT:techniques involved stay accessible to the public at large, I have to XT:make the following stipulations: XT: XT: 1) This program and source code may be freely distributed as long as no XT: profits are made in the process (Club Disks of the Month and BBSs are XT: excepted, of course.) XT: 2) All derivatives of the routines in this code must include this notice XT: verbatim and are similarly subject to the conditions in 1, above. XT: 3) No warrantees are made as to the usefulness or safety of using this XT: code. The user uses it at his/her own risk. X X#:41 X1:030 X2:540 XX:14 XY:15 XT: Todd Burkey A member of STdNET XT: 3546 Pilgrim Lane The ST developers' Network XT: Plymouth, MN 55441 (trb@stag.UUCP) X X#:42 XX:10 XY:6 XT: SIMPLE TESTING X+:Look at sample.txt X=:10 X+:Look at bad file X=:11 X+:Open Menu >100 X=:120 X+:Menu Doesn't exist X=:88 X+:Goto myself (loop) X=:42 X X/* Real help for POPHELP */ X#:3 XX:12 XY:8 XT:GETTING STARTED X+:Moving Around X=:22 X+:Some Comments X=:23 X+:Technical Info X=:26 X X#:26 XX:30 XY:10 X+:MENU.TRB Format X=:27 X+:COLOR Tables X=:28 X X#:27 XX:3 XY:4 XT:The file MENU.TRB is processed by POPHELP's build_menu routine and XT:drives the entire menu structure of POPHELP. The format of MENU.TRB XT:is very simple. For example, the following is a sample 2 level menu XT:with comments (note the comments can't really be part of the line): XT:#:1 <-we are defining menu # 1 XT:X:10 <-the popup box will start at cursor column 10 XT:Y:4 <-and at cursor row number 4 XT:T:WELCOME <-just some text to put in red (color #1) XT:+:More Help <-text for another menu selection XT:=:2 <-go to menu 2 when the above text is selected XT:#:2 <-all done with menu 1, so lets define menu 2 now XT:X:5 <-new coordinates XT:Y:6 <-new coordinates XT:1:070 <-redefine color 1 (the text) to be green (RGB) XT:<:afile.txt <-menu 2 popup text is read from a file X X#:60 XX:20 XY:8 X1:530 X2:053 XT:For RGB users only XT: You were warned X+:Some soft colors X=:61 X+:Some Putrid ones X=:62 X+:Late night colors X=:63 X X#:61 XX:5 XY:3 X0:054 X1:410 X2:046 X3:222 XT:Pastels? XT:0:054 XT:1:500 XT:2:066 XT:3:333 X X#:62 XX:5 XY:3 X0:070 X1:770 X2:077 X3:707 XT:Putrid XT:0:070 XT:1:770 XT:2:077 XT:3:707 X X#:63 XX:5 XY:3 X0:000 X1:700 X2:007 X3:770 XT:Brighter XT:0:000 XT:1:700 XT:2:007 XT:3:770 X X#:28 XX:2 XY:4 XT:Colors can be changed from the default setup dynamically within the menus, XT:but extreme care should be taken so you don't screw things up for people XT:who use monochrome monitors. The technique is quite simple. Within the XT:MENU.TRB file, include the following fields when you want a new color: XT:0:006 <--change color 0 to light blue (normal background) XT:1:600 <--change color 1 to red (non-selectable text) XT:2:000 <--change color 2 to black (for the shadow) XT:3:775 <--change color 3 to off white (popup background). XT:Note that the default color can be over-ridden by specifying a new color XT:for menu # 1 (the first popup that is displayed by POPHELP). X+:Some sample colors maps. X=:60 X X#:22 XX:14 XY:10 X+:ARROW KEYS X=:24 X+:HOW TO QUIT X=:25 X X#:25 XX:40 XY:12 XT:1) Press the ESC key. This takes XT: you out of the help selection. XT:2) Press the Q (not q) key. This XT: exits you from the demo. X X#:24 XX:30 XY:12 XT:RIGHT ARROW = Select the hilited menu XT:LEFT ARROW = Move to menu we came from XT:UP ARROW = Move up in the menu list XT:DOWN ARROW = Move down in the list X X#:23 XX:15 XY:11 XT:POPHELP is a simple, but clean, mechanism XT:for both externalized and internally held XT:help information. It was written only for XT:fun, but may prove useful in standardized XT:help utilities as its' features are tuned XT:up and refined. Any comments from anyone XT:out there? Or is this idea just too wierd XT:and far-fetched. X X/* lower level menu that is all text */ X#:4 XX:30 XY:14 XT:This is all Text, so you XT:can't really do much but XT:look at it and then push XT:the left arrow key. X X/* small menu */ X#:6 XX:50 XY:3 XT:Menu 6 X+:GOTO 5 X=:5 X+:GOTO 1 X=:1 X X/* menu that is really a file */ X#:10 XX:3 XY:5 X<:sample.txt X X/* just a test to show what a missing file will do */ X#:11 XX:3 XY:5 X<:hl.txt X X/* another little text menu */ X#:5 XX:70 XY:20 XT:JUST XT:MORE XT:Text SHAR_EOF chmod 0600 MENU.TRB || echo "restore of MENU.TRB fails" sed 's/^X//' << 'SHAR_EOF' > README.TRB && X/* This isn't meant to be read THIS way! Run README.PRG and check it out. */ X/* This file MUST be in the same directory as README.PRG for README to run. */ X/* Since you are looking at this file, note that this is the file that makes */ X/* up the beginning display when you first invoke README.PRG. By replacing */ X/* This page with your own, and making your own MENU.TRB file, you will have */ X/* your own customized standalone help reader */ X X POPUP HELP MENU DEMO X by Todd Burkey X X Hate clicking on and paging through README files? Well, give this program a X try. README.PRG is a standalone program that uses my POPUP HELP mechanism to X create nice, heirarchical help menus. Originally intended for HDSCAN, I have X decided to release this README application w/source code so others out there X can use it, learn from it, and hopefully even improve on it. POPHELP is easy X to use, just press HELP and use the arrows to move around. Press HELP again X (while inside POPHELP) if you get confused. Yep, even mono-chrome and mouse X lovers are supported. Some technical notes: X X 1) POPHELP is file driven. A procedure reads in MENU.TRB which describes X the popup hierarchy. Think of this as a help resource file. X 2) POPHELP has a limit of 100 popup menus (as compiled herein). Menu 0 is X for people who get confused. X 3) Short (<24 line) files can be automatically shown (see the examples.) SHAR_EOF chmod 0600 README.TRB || echo "restore of README.TRB fails" sed 's/^X//' << 'SHAR_EOF' > SAMPLE.TXT && X/* SAMPLE Two level Tree */ X#:1 XX:5 XY:15 XT:WELCOME TO POPHELP X+:Some Error Testing X=:42 X X#:42 XX:10 XY:6 XT:LEVEL TWO MENU X+:Goto menu 1 X=:1 X+:Menu Doesn't exist X=:88 SHAR_EOF chmod 0600 SAMPLE.TXT || echo "restore of SAMPLE.TXT fails" exit 0