home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MADTRB15.ZIP / MENUMOD.INC < prev    next >
Encoding:
Text File  |  1986-01-21  |  11.8 KB  |  374 lines

  1. {MenuMod.inc:  A module to insert into your programs to supply highlighted
  2.                menu selections.  The function "Menu" which begins on line
  3.                162 of this listing is the main routine calling the others in
  4.                the listing.  Before calling "Menu" you must initialize the
  5.                array "Menu_Selections" to be the prompts you wish to use.
  6.                "Menu" will return an integer corresponding to the subscript
  7.                of the prompt which was chosen.  The last item in the array
  8.                must be the null string.
  9.                }
  10. Type
  11.   Menu_Item       = String[76];
  12.   Menu_Selections = Array[1..15] of Menu_Item;
  13.   Long_String     = String[255];
  14.  
  15.  
  16. Function Upper_Left_X : Integer;       {* These four routines allow a       *}
  17.                                        {* routine to adjust its output      *}
  18. Begin                                  {* according to what size window it  *}
  19.   Upper_Left_X := Mem[Dseg:$156] + 1;  {* is operating in.  They are        *}
  20. End;                                   {* compatible only with Turbo Pascal *}
  21.                                        {* version 2.0 on an IBM PC or       *}
  22. Function Upper_Left_Y : Integer;       {* compatible                        *}
  23. Begin
  24.   Upper_Left_Y := Mem[Dseg:$157] + 1;
  25. End;
  26.  
  27. Var
  28.   Lower_Right_X : Byte Absolute Cseg:$16A;
  29.   Lower_Right_Y : Byte Absolute Cseg:$16B;
  30.  
  31.  
  32. Procedure RvsOn;                       {*  These two routines turn on and
  33.                                            off Reverse video on the IBM PC  *}
  34. Begin
  35.   TextColor(0);
  36.   TextBackGround(7);
  37. End;
  38.  
  39.  
  40. Procedure RvsOff;
  41. Begin
  42.   LowVideo;
  43. End;
  44.  
  45.  
  46. Procedure Inc(                     {* Increment argument by One             *}
  47.           Var I : Integer);
  48. Begin
  49.   I := I + 1;
  50. End;
  51.  
  52.  
  53. Function Lower (S : Long_String)    {* Convert string S to lowercase        *}
  54.                : Long_String;       {* Return lowercase string              *}
  55. Var
  56.   I : Integer;
  57.   ucase : Set of Char;
  58.  
  59. Begin
  60.   ucase := ['A'..'Z'];
  61.   For I := 1 to Length(S) do
  62.     If S[I] in ucase then S[I] := Char(Ord(S[I]) + 32);
  63.   lower := S;
  64. End;
  65.  
  66.  
  67. Procedure Click;                       { Makes a clicking noise }
  68. var f,n : integer;
  69.  
  70. Begin
  71.   Sound(2000);
  72.   Delay(10);
  73.   NoSound;
  74. End;
  75.  
  76.  
  77. Function Replicate (                          {* Repeat a character         *}
  78.                      Count : Integer;         {* Number of Repititions      *}
  79.                      Ascii : Char             {* Character to be repeated   *}
  80.                     )      : Long_String;     {* String containing repeated *}
  81.                                               {* character                  *
  82.  * This function takes the character in 'Ascii', repeats it 'Count' times   *
  83.  * and returns the resulting string as a 'Long_String'                      *}
  84.  
  85. Var
  86.   Temp : Long_String;  {Used to hold the incomplete result}
  87.   I    : Byte;         {For Counter}
  88.  
  89. Begin
  90.   Temp := '';
  91.   For I := 1 to Count do
  92.     Temp := Temp + Ascii;
  93.   Replicate := Temp;
  94. End; {Replicate}
  95.  
  96.  
  97.  
  98. Function Center (                              {* Centers a string in field *}
  99.                   Field_Width   : Byte;        {* Width of field for center *}
  100.                   Center_String : Long_String  {* String to Center          *}
  101.                 )               : Long_String; {* Return the string         *}
  102. {************************************************                           *
  103.  * This functions takes the string 'Center_String' and centers it in a      *
  104.  * field 'Field_Width' Spaces long.  It returns a 'Long_String' with a      *
  105.  * length equal to 'Field_Width'.  If the 'Center_String' is longer than    *
  106.  * field width, it is truncated on the right end and is not centered.       *}
  107.  
  108. Var
  109.   Temp   : Long_String;
  110.   Middle : Byte;
  111.  
  112. Begin
  113.   Middle := Field_Width div 2;
  114.   If Length(Center_String) > Field_Width then
  115.     Center := Copy(Center_String,1,Field_Width) {Truncate and return}
  116.   Else
  117.     Begin
  118.     Temp := Replicate(Middle - (Length(Center_String) div 2),' ') +
  119.             Center_String +
  120.             Replicate(Middle - (Length(Center_String) div 2) + 1,' ');
  121.     Center := Copy(Temp, 1, Field_Width)  {Truncate to Field_Width Characters}
  122.     End {Else}
  123.  End; {Center}
  124.  
  125.  
  126.  
  127. procedure Frame(                      {* Frame the section of screen within *}
  128.                 UpperLeftX,           {* these bounds                       *}
  129.                 UpperLeftY,
  130.                 LowerRightX,
  131.                 LowerRightY: Integer);
  132.   var
  133.     i: Integer;
  134.  
  135. begin
  136.   GotoXY(UpperLeftX,UpperLeftY);
  137.   Write(Chr(218));
  138.   GotoXY(UpperLeftX,LowerRightY);
  139.   Write(Chr(192));
  140.   GotoXY(LowerRightX,UpperLeftY);
  141.   Write(Chr(191));
  142.   GotoXY(LowerRightX,LowerRightY);
  143.   Write(Chr(217));
  144.   For I := UpperLeftX + 1 to LowerRightX - 1 do
  145.     Begin
  146.     GotoXY(I,UpperLeftY);
  147.     Write(Chr(196));
  148.     GotoXY(I,LowerRightY);
  149.     Write(Chr(196));
  150.     End;
  151.   For I := UpperLeftY + 1 to LowerRightY - 1 do
  152.     Begin
  153.     GotoXY(UpperLeftX,I);
  154.     Write(Chr(179));
  155.     GotoXY(LowerRightX,I);
  156.     Write(Chr(179));
  157.     End;
  158. end;  { Frame }
  159.  
  160.  
  161. {****************************************************************************}
  162. Function Menu (                               {* Display a Menu             *}
  163.                 Item_List  : Menu_Selections; {* List of Options on Menu    *}
  164.                                               {* Last Item must be Null     *}
  165.                                               {* String for proper operation*}
  166.                                               {* No more than 14 items per  *}
  167.                 Menu_X     : Integer;         {* X Location of Menu         *}
  168.                                               {* If Menu_X = 0 then the     *}
  169.                                               {* Menu is centered on the    *}
  170.                                               {* Screen                     *}
  171.                 Menu_Y     : Integer;         {* Y Location of Menu         *}
  172.                 Menu_Title : Menu_Item;       {* Title of Menu              *}
  173.                 Title_X    : Integer;         {* X Location of Title        *}
  174.                                               {* If Title_X = 0 then the    *}
  175.                                               {* Title is centered on the   *}
  176.                                               {* screen                     *}
  177.                 Title_Y    : Integer;         {* Y Location of Title        *}
  178.                 Default    : Integer          {* Default Selection          *}
  179.               )            : Integer;         {* Return the index of the    *}
  180.                                               {* item selected by the user  *}
  181.                                               {*                            *}
  182. {***********************************************                            *
  183. * This Routine Displays a Menu on the screen at the location specified by   *
  184. * Menu_X and Menu_Y.  The Menu Title is displayed in Reverse Video at the   *
  185. * Location specified by Title_X and Title_Y.  The User selects an item from *
  186. * the menu by using <CTRL>-E to move a reverse video cursor bar up and      *
  187. * <CTRL>-X to move it down.  After the cursor is on the item desired by the *
  188. * user, he must press return.  At this point the routine returns the item   *
  189. * number of the selection.                                                  *
  190. *****************************************************************************}
  191.  
  192. Const
  193.   CR = #13;
  194.   Up = #5;
  195.   Dn = #24;
  196.  
  197. Var
  198.   Inchar         : char;
  199.   Menu_Pointer   : 1..15;
  200.   Menu_Length    : 1..15;
  201.   Last           : Integer;
  202.   Width          : Integer;
  203.   Len            : Integer;
  204.   X1,X2,Y1,Y2    : Integer;
  205.   I,j,k          : integer;
  206.   instr          : long_string;
  207.  
  208. Begin {Menu}
  209.  
  210.   instr := '';
  211.  
  212.   Width := Lower_Right_X - Upper_Left_X + 1;   {Calculate Window Size}
  213.   Len   := Lower_Right_Y - Upper_Left_Y + 1;
  214.  
  215.   If Title_X <> 0 then       {position for the title}
  216.     GotoXY(Title_X,Title_Y)
  217.   Else
  218.     GotoXY(1,Title_Y);
  219.  
  220.   RvsOn;
  221.  
  222.   If Title_X = 0 Then                 {Write the title}
  223.     Write(Center(Width,Menu_Title))
  224.   Else
  225.     Write(Menu_Title);
  226.  
  227.   RvsOff;
  228.  
  229.   If Width > 38 then        {If there is enough room, write out instructions}
  230.     Begin                   {otherwise, they is out a luck}
  231.     Frame(1,Len-3,Width-1,Len);
  232.     GotoXY((Width div 2) - 6,Len-3);
  233.     Write(#17);
  234.     RvsOn;
  235.     Write('Instructions');
  236.     RvsOff;
  237.     Write(#16);
  238.     TextColor(15);
  239.     GotoXY(2,Len-2);
  240.     Write(Center(Width-3,'Use '+#24+' and '+#25+' to Highlight a Selection'));
  241.     GotoXY(2,Len-1);
  242.     Write(Center(Width-3,' And <CR> to make the Selection'));
  243.     TextColor(7);
  244.     End;
  245.  
  246.   Inchar := ' ';               {Initialize variables}
  247.   Menu_Pointer := 1;
  248.  
  249.   {Display the actual menu selections and determine how many selections
  250.    are available}
  251.  
  252.   While (Menu_pointer <=15) and (length(Item_list[Menu_pointer]) > 0) do
  253.  
  254.     Begin
  255.     If Menu_X <> 0 then
  256.       Begin
  257.       GotoXY(Menu_X,Menu_Y - 1 + Menu_Pointer);
  258.       Write(Item_List[Menu_Pointer])
  259.       End {If}
  260.     Else
  261.       Begin
  262.       GotoXY(1,Menu_Y - 1 + Menu_Pointer);
  263.       Write(Center(Width-1,Item_List[Menu_Pointer]))
  264.       End; {Else}
  265.     Menu_Pointer := Menu_Pointer + 1;
  266.     End;  {While}
  267.  
  268.   Menu_Length := Menu_Pointer - 1;
  269.   Menu_Pointer := Default;
  270.  
  271.   While inchar <> CR do          {Main loop}
  272.  
  273.     Begin
  274.     If Menu_X <> 0 then
  275.       Begin
  276.       GotoXY(Menu_X,Menu_Pointer - 1 + Menu_Y); {Highlight the current menu}
  277.       RvsOn;                                    {item}
  278.       Write(Item_List[Menu_Pointer]);
  279.       RvsOff;
  280.       End {If}
  281.     Else
  282.       Begin
  283.       GotoXY(1,Menu_Pointer - 1 + Menu_Y);
  284.       RvsOn;
  285.       Write(Center(Width-1,Item_List[Menu_Pointer]));
  286.       RvsOff;
  287.       End; {Else}
  288.  
  289.     Read(Kbd,Inchar);    {get a character from the user}
  290.     Click;
  291.  
  292.     Last := Menu_Pointer;
  293.  
  294.     If Not (Inchar in [^[,Up,Dn,Cr]) then
  295.  
  296.       Begin
  297.  
  298.       if inchar = #127 then
  299.         instr := ''
  300.       else
  301.  
  302.         if inchar = ^H then
  303.           delete(instr,length(instr),1)
  304.         else
  305.           instr := instr + inchar;
  306.  
  307.       j := 0;
  308.       k := 0;
  309.  
  310.       for i := 1 to Menu_Length do
  311.  
  312.         if lower(instr) = lower(copy(item_list[i],1,length(instr))) then
  313.  
  314.           begin
  315.           inc(j);
  316.  
  317.           if k = 0 then
  318.             k := i;
  319.  
  320.           end;
  321.  
  322.       if k <> 0 then
  323.         menu_pointer := k;
  324.  
  325.       if (j = 1) or (j = 0) then
  326.         instr := '';
  327.  
  328.       end;
  329.  
  330.     If (Inchar = ^[) and KeyPressed then   {get the escape code}
  331.       Read(Kbd, Inchar);
  332.  
  333.     If Inchar = ';' Then
  334.       Begin
  335.       X1 := Upper_Left_X;
  336.       Y1 := Upper_Left_Y;
  337.       X2 := Lower_Right_X;
  338.       Y2 := Lower_Right_Y;
  339.       {Help;}
  340.       Window(X1,Y1,X2,Y2);
  341.       End;
  342.  
  343.     If (Inchar = Up) Or (Inchar = 'H') then
  344.       Begin                                    {They hit up arrow}
  345.       Menu_Pointer := Menu_Pointer - 1;
  346.       If Menu_Pointer < 1 then
  347.         Menu_Pointer := Menu_Length;
  348.       instr := '';
  349.       End;  {If}
  350.  
  351.     If (Inchar = Dn) Or (Inchar = 'P') then
  352.       Begin                                    {They hit down arrow}
  353.       Menu_Pointer := Menu_Pointer + 1;
  354.       if Menu_Pointer > Menu_Length then
  355.         Menu_Pointer := 1;
  356.       instr := '';
  357.       end;  {If}
  358.  
  359.     If Menu_X <> 0 then                        {UnHighlight the old selection}
  360.       Begin
  361.       GotoXY(Menu_X, Last - 1 + Menu_Y);
  362.       Write(Item_List[Last]);
  363.       End {If}
  364.     Else
  365.       Begin
  366.       GotoXY(1, Last - 1 + Menu_Y);
  367.       Write(Center(Width-1,Item_List[Last]));
  368.       End; {Else}
  369.  
  370.     End; {While};                           {They made a selection, beep once}
  371.   Menu := Menu_Pointer;                     {to confirm}
  372.  
  373. end; {Menu}
  374.