MenuProgram

From Pickwiki
Revision as of 23:48, 26 February 2015 by Conversion script (talk) (link fix)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Back to BasicSource

This is a very simple menu program which allows you to do single key entry. There are a maximum of 36 options available which you can assign to the number and letter keys. If there is less that 18 options, it displays a single column in the centre of the page. If more than 18, it shows two columns. Documentation is in the program source.

      PROGRAM MENU
*
* Utility program to run a menu system - very simple and short.
* The code is supplied on an as-is basis as a source-code resource.
* No representation whatever is made as to the operation of the program.
*
* Keith Johnson.
*
* Items in the menu file have 37 attributes, any more are ignored
* The first line is the menu title.  The other 36 are options
* which can be called by numbers 0-9 and letters A-Z>
*
* Each option line consists of X fields using \ as separator
* so they can be easily edited (or a value mark can be used)
*
* The fields are
* 1: TYPS - 'M' for another menu, 'T' a title, 'C' a command to execute
* 2: CMDS - The letter or number to select this option (is highlighted)
* 3: THIS - Display line
* 4: ACTS - The command to execute or menu to read
* 5: INPS - 'Y' if input is required or help is available
* 6: PMTS - Prompt used before input requested or a help text
* 7: HIGH - 'Y' if the user requires high security to access this
*
* High security is that the users @LOGNAME is held on a file
* called XXXXXX in line 2 of an item called HIGHSECURITY
* in a list separated by value marks or backslashes (\).
* This is actually subverted in the following code - you can
* roll your own (and I encourage you to do so).

      PROMPT ''
      GOOD = (1=1)
      EVIL = NOT(GOOD)
      ATTM = CHAR(254)
      VALM = CHAR(253)
      BELL = STR(CHAR(7),20)

      CLRS = @(-01); CEOL = @(-04)
      RVON = @(-13); RVOF = @(-14)
      ULON = @(-15); ULOF = @(-16)

      NEWP = GOOD
      NAME = 'MAIN'
      MENULIST = ''
      NUMBMENU = 0
      OPEN 'MENUFILE' TO MENUFILE ELSE STOP 201,'MENUFILE'
      READ MENU FROM MENUFILE,NAME ELSE
         STOP 'Cannot read ':NAME:' from MENUFILE'
      END

* These next 4 lines may have to be changed
      USER = @LOGNAME
      PORT = @USERNO
      ACCT = @WHO
      PATH = @PATH

      USER = OCONV(USER,'MCT')
      MAST = OCONV('XXXXXXX','THIGHSECURITY;X;;2')
      MAST = OCONV(MAST,'MCT')
      CONVERT '\' TO VALM IN MAST
      CONVERT VALM TO ATTM IN MAST
*
* Above is control mechanism, we will now subvert it deliberately.
      MAST = USER
*

      LOOP
         GOSUB SHOW.MENU
      UNTIL CHOICE = ''
         IF CHOICE = 'M' THEN MENU = THISUN ELSE
            IF CHOICE = 'C' THEN
               EXECUTE THISUN
               CRT 'Press <ENTER> to return to menu':;INPUT WAIT:
               NEWP = GOOD
            END
         END
      REPEAT
      GOSUB ERASE.SCREEN
      STOP


************************************************************************
* SUBROUTINES
************************************************************************
ERASE.SCREEN:
      FOR AA = SYSTEM(3)-1 TO 0 STEP -1
         CRT @(00,AA):CEOL:
      NEXT AA
      RETURN


SHOW.MENU:
      IF NEWP THEN
         CRT CLRS:
         NEWP = EVIL
      END ELSE
         GOSUB ERASE.SCREEN
      END
      TITLE = NAME:' MENU'
      IF MENU<1> NE ''THEN TITLE = MENU<1>
      TPOS = 40-((LEN(TITLE))/2)
      TITLE = @(TPOS,00):ULON:TITLE:ULOF
      TITLE := @(00,00):PATH
      TITLE := @(00,01):TIMEDATE()
      TITLE := @(70,00):ACCT

      TITLE := @(70,01):USER:'|':PORT
      CRT TITLE
      LINCNT = DCOUNT(MENU,ATTM)
      IF LINCNT GT 37 THEN LINCNT = 37
      NUMB = 0
      TYPS = ''
      CMDS = ''
      THIS = ''
      ACTS = ''
      INPS = ''
      PMTS = ''
      HIGH = ''
      XPOS = 1
      IF LINCNT LE 19 THEN XPOS = 25
      FOR LIN = 2 TO LINCNT
         LINE = MENU<LIN>
         CONVERT '\' TO VALM IN LINE
         IF LIN GT 19 THEN XPOS = 40
         YPOS = REM(LIN-2,18) + 3
         SUPP = EVIL
         IF LINE<1,7> THEN
            LOCATE(USER,MAST;MPOS) ELSE SUPP = GOOD
         END
         BEGIN CASE
            CASE TRIM(LINE) = ''
               NULL
            CASE LINE<1,1> = 'T'
               CRT @(XPOS,YPOS):'  ':ULON:LINE<1,3>:ULOF:
            CASE SUPP
               CRT @(XPOS,YPOS):LINE<1,3>:
            CASE 1
               ZPOS = INDEX(OCONV(LINE<1,3>,'MCU'),OCONV(LINE<1,2>,'MCU'),1)
               IF ZPOS THEN
                  CRT @(XPOS,YPOS):LINE<1,3>[1,ZPOS-1]:
                  CRT RVON:LINE<1,3>[ZPOS,1]:
                  CRT RVOF:LINE<1,3>[ZPOS+1,LEN(LINE<1,3>)-ZPOS]:
               END ELSE
                  CRT @(XPOS,YPOS):RVON:LINE<1,2> 'L#1':
                  CRT RVOF:' ':LINE<1,3>:
               END
               NUMB += 1
               TYPS<NUMB> = LINE<1,1>
               CMDS<NUMB> = LINE<1,2>
               THIS<NUMB> = LINE<1,3>
               ACTS<NUMB> = LINE<1,4>
               INPS<NUMB> = LINE<1,5>
               PMTS<NUMB> = LINE<1,6>
               HIGH<NUMB> = LINE<1,7>
         END CASE
      NEXT LIN

LOOP.INPUT:
      LOOP
         CRT @(00,22):CEOL:'Press choice ':
         IF SYSTEM(11) THEN CRT '>': ELSE CRT ':':
         INPUT REPLY,1:
         REPLY = OCONV(REPLY,'MCU')
         CPOS = 0
         IF REPLY = '/' OR REPLY = CHAR(27) THEN REPLY = ''
         IF REPLY = '' THEN
            IF NUMBMENU THEN
               NAME = MENULIST<NUMBMENU>
               READ THISUN FROM MENUFILE, NAME ELSE
                  STOP 'Cannot read ':NAME:' from MENUFILE'
               END
               DEL MENULIST<NUMBMENU>
               NUMBMENU -= 1
               CHOICE = 'M'
            END ELSE CHOICE = ''
         END ELSE
            LOCATE(REPLY,CMDS;CPOS) THEN
               REPLY = ''
            END ELSE NULL
         END
      UNTIL REPLY = ''
         CRT BELL:
      REPEAT

      IF CPOS THEN
         IF HIGH<CPOS> THEN
            LOCATE(USER,MAST;MPOS) ELSE RETURN
         END
         CHOICE = TYPS<CPOS>
         DISP = THIS<CPOS>
         THISUN = ACTS<CPOS>
         IF CHOICE = 'M' THEN
            READ THISUN FROM MENUFILE, THISUN ELSE
               CRT BELL:
               GO LOOP.INPUT
            END
            NUMBMENU += 1
            MENULIST<NUMBMENU> = NAME
            NAME = ACTS<CPOS>
         END
         PRMT = PMTS<CPOS>
         GOSUB ERASE.SCREEN
         CRT RVON:OCONV(DISP,'MCU'):RVOF
         IF INPS<CPOS> = 'Y' THEN
            IF PRMT = '' THEN
               PRMT = 'Input possible - or null to see help'
            END
            CRT PRMT
            CRT THISUN:' ':
            INPUT BIGUN:
            BEGIN CASE
               CASE BIGUN = CHAR(27) OR BIGUN = '/'
                  CHOICE = 'M'
                  THISUN = MENU
               CASE BIGUN NE ''
                  THISUN := ' ':BIGUN
            END CASE
         END ELSE
            IF PRMT NE '' THEN CRT PRMT
         END
      END
      RETURN