home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MPICKE.ZIP / PICKER.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-08-16  |  8.8 KB  |  302 lines

  1. UNIT Picker;
  2. (*********************************************************************)
  3. (*  UNIT PICKER                                                      *)
  4. (*********************************************************************)
  5. (*  Public domain routines for anyone's free use                     *)
  6. (*  BY:  Frank H Carr         August 16, 1988                        *)
  7. (*       Compuserve           71121,3247                             *)
  8. (*       Gene Plantz IBBS     (312) 885-2303  ID0434                 *)
  9. (*********************************************************************)
  10.  
  11. INTERFACE
  12.  
  13. USES
  14.   crt;
  15.  
  16. TYPE
  17.   menu = array[1..128] of string[15];
  18.   boxpattern=string[9];
  19.  
  20.  Function Replicate(ch:char; num:integer):string;
  21.  Procedure DrawBox(c1,r1,c2,r2:byte; box:boxpattern);
  22.  Function Achoice(m:menu; col,row,num,depth,cols,position:byte):byte;
  23.  
  24.  
  25. IMPLEMENTATION
  26.  
  27. (****************************************************)
  28. (* FUNCTION REPLICATE                               *)
  29. (* Returns a string of repeated characters.         *)
  30. (****************************************************)
  31. Function Replicate(ch:char; num:integer):string;
  32. Var
  33.  tempstr:string;
  34. Begin
  35.  tempstr:='';
  36.  while num>0 do
  37.    begin
  38.      tempstr:=tempstr+ch;
  39.      dec(num);
  40.    end;
  41.  replicate:=tempstr;
  42. End;
  43.  
  44. (****************************************************)
  45. (* PROCEDURE DRAWBOX                                *)
  46. (* Draws a box using box pattern. First coordinates *)
  47. (* are upper left corner, second coordinates are    *)
  48. (* lower right.                                     *)
  49. (****************************************************)
  50. Procedure DrawBox(c1,r1,c2,r2:byte; box:boxpattern);
  51. Var
  52.  i,width:integer;
  53. Begin
  54.  width:=c2-c1-1;
  55.  gotoxy(c1,r1);
  56.  write(box[1],replicate(box[2],width),box[3]);
  57.  for i:=r1+1 to r2-1 do
  58.   begin
  59.    gotoxy(c1,i);
  60.    write(box[4],replicate(' ',width),box[8]);
  61.   end;
  62.  gotoxy(c1,r2);
  63.  write(box[7],replicate(box[6],width),box[5]);
  64. End;
  65.  
  66.  
  67. (****************************************************)
  68. (* FUNCTION ACHOICE                                 *)
  69. (* Returns the array element number of the choice   *)
  70. (* picked. Returns a 0 if <Esc> was pressed.        *)
  71. (* Parameters: m - an string array of choice names  *)
  72. (*             col,row - the upper left coordinates *)
  73. (*                       of the box                 *)
  74. (*             num - the number of elements in the  *)
  75. (*                   array (choices)                *)
  76. (*             depth - the number of choices        *)
  77. (*                     displayed verticaly          *)
  78. (*             cols - the number of choices         *)
  79. (*                    displayed horizontaly         *)
  80. (*             position - The default choice        *)
  81. (****************************************************)
  82. Function Achoice(m:menu; col,row,num,depth,cols,position:byte):byte;
  83.  
  84. Var
  85.   i,maxlen,width,oldcol,oldrow,top:byte;
  86.   ch:char;
  87.   box:boxpattern;
  88.  
  89.  (*****************************)
  90.  (* function colnum           *)
  91.  (* returns the column number *)
  92.  (* from 1 to cols            *)
  93.  (*****************************)
  94.  function colnum(p,c:byte):byte;
  95.  begin
  96.   colnum:=(p-1) mod c;
  97.  end;
  98.  
  99.  (*****************************)
  100.  (* procedure inverseon       *)
  101.  (* sets inverse display mode *)
  102.  (*****************************)
  103.  procedure inverseon;
  104.  Begin
  105.   textcolor(0);
  106.   textbackground(7);
  107.  End;
  108.  
  109.  (*****************************)
  110.  (* procedure inverseoff      *)
  111.  (* sets regular display mode *)
  112.  (*****************************)
  113.  procedure inverseoff;
  114.  begin
  115.   textcolor(7);
  116.   textbackground(0);
  117.  end;
  118.  
  119.  (*****************************)
  120.  (* function firstletter      *)
  121.  (* returns the first non-    *)
  122.  (* blank character of a      *)
  123.  (* string                    *)
  124.  (*****************************)
  125.  function firstletter(str:string):char;
  126.  var
  127.    i:byte;
  128.  begin
  129.    i:=0;
  130.    repeat
  131.      inc(i);
  132.    until str[i]<>' ';
  133.    firstletter:=upcase(str[i]);
  134.  end;
  135.  
  136.  (*****************************)
  137.  (* procedure dispmenu        *)
  138.  (* prints the selections     *)
  139.  (* available in the box      *)
  140.  (*****************************)
  141.  procedure dispmenu;
  142.  var
  143.    i,colcount,rowcount:byte;
  144.  begin
  145.    colcount:=0;
  146.    rowcount:=0;
  147.    for i:=top to top+(depth*cols)-1 do
  148.      begin
  149.        gotoxy(col+(colcount*maxlen),row+rowcount);
  150.        if cols > 1 then
  151.          inc(colcount)
  152.        else
  153.          inc(rowcount);
  154.        if colcount = cols then
  155.          begin
  156.            colcount:=0;
  157.            inc(rowcount);
  158.          end;
  159.        if i <= num then
  160.          if i=position then
  161.            begin
  162.              inverseon;
  163.              write(m[i]);
  164.              inverseoff;
  165.            end
  166.          else
  167.            write(m[i])
  168.        else
  169.          write(replicate(' ',maxlen));
  170.      end;
  171.    gotoxy(col+1,row-1);
  172.    if top > 1 then
  173.      write('['+#24+']')
  174.    else
  175.      write(replicate(box[2],3));
  176.    gotoxy(col+(cols*maxlen)-3,row+depth);
  177.    if top < num-colnum(num,cols)-(depth*cols)+1 then
  178.      write('['+#25+']')
  179.    else
  180.      write(replicate(box[6],3));
  181.  end;
  182.  
  183.  
  184. Begin   (***** of Achoice *****)
  185.          { save old coords and find maximum length }
  186.   oldcol:=wherex;
  187.   oldrow:=wherey;
  188.   box:='╔═╗║╝═╚║';
  189.   top:=position-colnum(position,cols);
  190.   if (depth > num) and (cols = 1) then
  191.     depth:=num;
  192.   if depth*cols > num then
  193.     depth:=(num-colnum(num,cols)+cols) div cols;
  194.   maxlen:=0;
  195.   for i:=1 to num do
  196.     if length(m[i]) > maxlen then
  197.       maxlen:=length(m[i]);
  198.          { make sure all lengths are the same }
  199.   for i:=1 to num do
  200.     m[i]:=m[i]+replicate(' ',maxlen-length(m[i]));
  201.  
  202.          { draw the box and display the menu initially }
  203.   drawbox(col,row,col+(maxlen*cols)+1,row+depth+1,box);
  204.   inc(col);
  205.   inc(row);
  206.   dispmenu;
  207.   ch:=#1;
  208.  
  209.          { begining of loop to execute until a choice is made }
  210.          { by pressing <Enter> or aborting with <Esc> }
  211.   repeat
  212.     gotoxy(oldcol,oldrow);
  213.     ch:=upcase(readkey);
  214.     if ch=#0 then
  215.       case readkey of
  216.         #71:begin                           {home}
  217.               position:=1;
  218.               top:=1;
  219.             end;
  220.         #79:begin                           {end}
  221.               position:=num;
  222.               top:=position-colnum(position,cols)-(cols*depth)+cols;
  223.             end;
  224.         #72:if position-cols >= 1 then           {up}
  225.               begin
  226.                 dec(position,cols);
  227.                 if position < top then
  228.                   dec(top,cols);
  229.               end;
  230.         #80:if position+cols <= num then         {down}
  231.               begin
  232.                 inc(position,cols);
  233.                 if position > top+(depth*cols)-1 then
  234.                   inc(top,cols);
  235.               end;
  236.         #75:if position > 1 then                 {left}
  237.               begin
  238.                 dec(position);
  239.                 if position < top then
  240.                   dec(top,cols);
  241.               end;
  242.         #77:if position < num then               {right}
  243.               begin
  244.                inc(position);
  245.                if position > top+(cols*depth)-1 then
  246.                  inc(top,cols);
  247.               end;
  248.         #81:if position+(depth*cols) < num then  {PgDn}
  249.               begin
  250.                 inc(position,depth*cols);
  251.                 top:=position-colnum(position,cols);
  252.                 if top > num-(depth*cols)+1 then
  253.                   top:=num-colnum(num,cols)-(depth*cols)+cols;
  254.               end
  255.             else
  256.               begin
  257.                 position:=num;
  258.                 top:=position-colnum(position,cols)-(cols*depth)+cols;
  259.               end;
  260.         #73:if position-(depth*cols) > 0 then    {PgUp}
  261.               begin
  262.                 dec(position,depth*cols);
  263.                 top:=position-colnum(position,cols);
  264.               end
  265.             else
  266.               begin
  267.                 position:=1;
  268.                 top:=1;
  269.               end;
  270.       end    { of case }
  271.     else
  272.       begin                            { if its not an extended }
  273.         i:=position;                   { scan code, check for }
  274.         repeat                         { a valid letter pressed }
  275.           inc(i);
  276.           if i > num then
  277.             i:=1;
  278.         until (i=position) or (firstletter(m[i])=ch);
  279.         if i <> position then
  280.           position:=i;
  281.         if position > top+(cols*depth)-1 then
  282.           inc(top,cols);
  283.         if position > top+(depth*cols)-1 then
  284.           top:=position-colnum(position,cols);
  285.         if top > num-(depth*cols)+1 then
  286.           top:=num-colnum(num,cols)-(depth*cols)+cols;
  287.         if position < top then
  288.           top:=position-colnum(position,cols);
  289.       end;
  290.       dispmenu;
  291.   until ch in [#27,#13];
  292.   if ch=#27 then
  293.     achoice:=0
  294.   else
  295.     achoice:=position;
  296.   gotoxy(oldcol,oldrow);
  297. End;
  298.  
  299.  
  300. BEGIN
  301. END.
  302.