[Back to MENU SWAG index]  [Back to Main SWAG index]  [Original]

(*
 SB> i have a problem. I want it to show Three Choices Like This;


 SB> Choice #1
 SB> Choice #2
 SB> Choice #3

 SB>
 SB> I want Choice #1 to be in White, and the others to be In Darkgray, if
 SB> they  press down, it will make only #2 White, and the others Darkgray,
 SB> if they press Down again it will make only Choice #3 White, and it will
 SB> Tell Them Which  Choice they choosed on each one if they press enter.
 SB> So if they press Enter  while Choice #1 Was Highlighted, it would say
 SB> 'You Chose Choice Number 1'. and and it will Repeat when you Press the
 SB> arrow keys, untill they press Enter on  anyone of the Choice Choices...

The following should get you started:
*)

PROGRAM Seans_Menu;

USES Crt;

FUNCTION readkeyword: word; ASSEMBLER;
{ -- Assumes you have an extended (i.e. non-XT) keyboard.
  -- Returns both scancode and character with one call. }
ASM mov ah, $10
    int $16
END;

CONST Down  = $5000;
      { -- Value returned by ReadKeyword for the down arrow key. }
      Up    = $4800;
      Enter = $1C0D;
      Esc   = $011B;

PROCEDURE menu(CONST nbr_of_choices: byte;
               VAR   selected      : byte;
               VAR   accept        : boolean);
{ -- Puts up a menu with NBR_OF_CHOICES choices.
  -- The user can use the up and down arrow keys to select a particular
  -- menu item. Enter then selects, and Esc exits immediately.
  -- On exit, if the user pressed Enter, ACCEPT will be TRUE, and SELECTED
  -- will hold the number of the selected item. If the user cancelled the
  -- selection (Esc pressed), ACCEPT will be FALSE, and SELECTED then is
  -- undefined. }
CONST StartingCol  = 5;  { -- These two determine the top left corner of }
      StartingRow  = 3;  { -- your menu. }
      NormalColour = DarkGray;
      HiliteColour = White;
      Str          = 'Choice #';
VAR j, TA: byte;

  PROCEDURE beep;
  BEGIN sound(700); delay(50); nosound END;

  PROCEDURE DrawCurrentlySelected;
  BEGIN gotoxy(StartingCol, StartingRow + selected - 1);
        write(Str, selected:1)
  END;

  PROCEDURE DoDown;
  BEGIN DrawCurrentlySelected;
        { -- Redraw current item in the normal, i.e. unselected, colour. }

        IF selected = nbr_of_choices THEN selected:=1 ELSE inc(selected);
        TextAttr:=HiliteColour;
        DrawCurrentlySelected;
        { -- Move cursor to newly selected item and redraw in the highlight,
          -- i.e. selected, colour. }
        TextAttr:=NormalColour
  END;

  PROCEDURE DoUp;
  BEGIN DrawCurrentlySelected;
        IF selected = 1 THEN selected:=nbr_of_choices ELSE dec(selected);
        TextAttr:=HiliteColour;
        DrawCurrentlySelected;
        TextAttr:=NormalColour
  END;

  PROCEDURE Process;
  { -- Keep reading keys until user decides s/he has had enough. }
  VAR finished: boolean;
      key     : word;
  BEGIN finished:=FALSE;
        REPEAT key:=readkeyword;
               CASE key
               OF Down : DoDown;
                  Up   : DoUp;
                  Enter: BEGIN finished:=TRUE; accept:=TRUE  END;
                  Esc  : BEGIN finished:=TRUE; accept:=FALSE END;
               ELSE beep
               END
        UNTIL finished
  END;
BEGIN (* menu *)
      gotoxy(StartingCol, StartingRow);

      TA:=TextAttr;
      { -- If you start messing with the screen colours, it is good
        -- manners to mark the current ones, so you can restore them
        -- when you're through. }

      { -- Now draw all items in the unselected colour: }
      TextAttr:=NormalColour;
      FOR j:=1 TO nbr_of_choices
      DO BEGIN gotoxy(StartingCol, StartingRow + j - 1);
               write(Str, j:1)
         END;

      { -- Do first item in selected colour: }
      TextAttr:=HiliteColour;
      selected:=1; DrawCurrentlySelected;
      TextAttr:=NormalColour;

      accept:=FALSE;
      Process;

      TextAttr:=TA
END;

PROCEDURE ColourClrscr(CONST Colour_U_Like: byte);
{ -- Clears the screen, colouring all positions.
  -- Not essential, just nice ... }
VAR TA: byte;
BEGIN TA:=TextAttr; TextAttr:=Colour_U_Like;
      clrscr;
      TextAttr:=TA
END;

{ -- Main: }

VAR choice: byte;
    ok    : boolean;

BEGIN ColourClrscr(Blue*16);
      menu(5, choice, ok);
      gotoxy(1, 20);
      IF ok
      THEN writeln('You chose nr. ', choice:1)
      ELSE writeln('You aborted ...')
END.


[Back to MENU SWAG index]  [Back to Main SWAG index]  [Original]