{ 4/8/87 20:39 Menus} ! The built-in function Set Up Menu expects the data to be given to it ! as an array of items, each with its name and value in a record. Each ! value is expected to be a list of lines. %include "sm:consts.inc" %include "sm:formats.inc" %include "sm:utils.inc" %include "inc:vtlib.imp" %recordformat dataf(%string(19) name,%record(line80listf) val) %recordformat menuf(%integer item,%string(19) name,%string(63) val) %ownrecord(menuf)%array menu(0:250) %owninteger cursorx,cursory %owninteger datastart=20 %externalstring(31) helpfile="menuhelp" %owninteger linelength=80, menudepth %externalroutinespec view(%string(255) file,topic) %owninteger wdepth=16, wmin, wmax %routinespec write menu %externalroutine screen message(%string(255) s,%string(15) mon) %integer oldout oldout=outstream select output(0) gotoxy(0,wdepth+1) clear line print string(s) %monitor %if mon="mon" %stop %if mon="stop" %or mon="mon" gotoxy(cursorx,cursory) select output(oldout) %end %externalrecord(line80f)%map newline80 %record(line80f) pattern %record(line80f)%name p p==new(pattern) p_next==nil; p_prev==nil p_line="" %result==p %end %routine h(%string(31) topic) %string(255) x, y topic=x." ".y %while topic->x.("_").y view(helpfile,topic) %end %externalroutine start screen mode {! If Vax.} { define video(vttype)} ! select input(0); select output(0) set video mode(screen mode+special pad) set frame(wdepth+1,24,0,80) clear frame push frame set frame(0,wdepth,0,80) clear frame gotoxy(0,0) cursorx=0; cursory=0 prompt("") %end %externalroutine stop screen mode clear frame set video mode(0) %end %externalroutine read screen line(%string(*)%name a) %integer j,k %string(255) u %on %event 15,0 %start read symbol(j) %until j=lf ;! To get rid of residual NL. h(menu(cursory)_name) write menu %finish prompt("") a="" cursorx=datastart gotoxy(cursorx,cursory-wmin) clear line %cycle read symbol(j) %exit %if j=lf %or j=enter %signal %event 15,0 %if j='?' screen message("Stopped at ".menu(cursory)_name,"stop") %if j=128+esc %continue %if j<=31 %or j>=128 %if j=del %thenstart ! This supposes that del has not been dealt with at the input. print symbol(sp) k=length(a) k=k-1; cursorx=cursorx-1 k=0 %if k<0; cursorx=datastart %if cursorxlinelength %finish gotoxy(cursorx,cursory-wmin) %repeat u=a; lower(u) cursorx=datastart; gotoxy(cursorx,cursory-wmin) clear line; print string(a) cursorx=0; gotoxy(cursorx,cursory-wmin) %end %externalroutine set up menu(%record(dataf)%arrayname data, %integer mask) %integer flag,i,j %record(line80f)%name p menu(i)=0 %for i=0,1,31 ! Ensure that items 0 and 31 are available for escape. mask=mask!16_80000001 menu(i)=0 %for i=0,1,250 j=0 %for i=0,1,31 %cycle %if mask&1=0 %then flag='n' %else flag='y' mask=mask>>1 %continue %if flag='n' ! Copy wanted item into menu. p==data(i)_val_head %if p==nil %thenstart menu(j)_item=i menu(j)_name=data(i)_name %if 0#i#31 %then menu(j)_val="*" %else menu(j)_val="" j=j+1 %finishelsestart %while p##nil %cycle menu(j)_item=i menu(j)_name=data(i)_name menu(j)_val=p_line j=j+1 p==p_next %repeat %finish %repeat menudepth=j-1 %end %externalroutine write instruction(%string(255) s) swop frame gotoxy(0,wdepth+4) clear line gotoxy(0,wdepth+3) clear line gotoxy(0,wdepth+2) clear line print string(s) swop frame gotoxy(cursorx,cursory) %end %routine display line(%integer y) gotoxy(0,y-wmin) clear line print symbol(' ') print string(menu(y)_name) gotoxy(datastart,y-wmin) print string(menu(y)_val) gotoxy(0,y-wmin) %end ! This will not alter anything if the item is not in the menu. %externalroutine write menu %integer d, i %string(255) s ! Bring position of cursor within menu. %if cursorx<0 %then cursorx=0 %else %c %if cursorx>linelength %then cursorx=linelength %if cursory<0 %then cursory=0 %else %c %if cursory>menudepth %then cursory=menudepth ! Adjust window depth to fit menu. d=wdepth; d=menudepth %if d>menudepth ! Adjust window to fit position of cursor. wmin=cursory-d//2; wmin=0 %if wmin<0 wmax=wmin+d; wmax=menudepth %if wmax>menudepth wmin=wmax-d; wmin=0 %if wmin<0 ! Display menu. display line(i) %for i=wmin,1,wmax ! Write instructions. s="Move the cursor to the appropriate line.".snl. %c "Type ? and press for help. Press to alter.".snl. %c "Type in the value and press again.".snl. %c "Move the cursor off the screen to see more of the menu." write instruction(s) ! Set cursor. gotoxy(cursorx,cursory-wmin) %end %externalintegerfn cursor depth %integer j select input(0) prompt("") gotoxy(0,cursory-wmin) %cycle read symbol(j) %exit %if j=lf %if j=down %then cursory=cursory+1 %else %c %if j=up %then cursory=cursory-1 %else %c %if j&127=esc %then %signal 15,3 %elsestart %if j='?' %thenstart read symbol(j) %until j=lf ;! get rid of residual NL. h(menu(cursory)_name) write menu %finish %continue %finish %if cursory<0 %then cursory=0 %else %c %if cursory>menudepth %then cursory=menudepth %if wmin<=cursory<=wmax %then %c gotoxy(0,cursory-wmin) %else write menu %repeat cursorx=datastart gotoxy(cursorx,cursory-wmin) %result=menu(cursory)_item %end %endoffile