home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / olbox100.zip / OLBOX.CMD next >
OS/2 REXX Batch file  |  1999-06-08  |  11KB  |  320 lines

  1. /*----------------------------------------------*/
  2. /* OLBOX.CMD -  Listbox In OREXX                */
  3. /* 1999 (C) Antal Koos,                         */
  4. /* Version: see LibVersion method!              */
  5. /*----------------------------------------------*/
  6. /* Load the RexxUtil in your program or in the startup.cmd! */
  7. /* Call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs';*/
  8. /* Call SysLoadFuncs;*/
  9.  
  10. return;
  11.  
  12. /*-------------------------------------*/
  13. ::CLASS OLBox Public
  14. /*-------------------------------------*/
  15. /*-------------------------------------*/
  16. ::METHOD LibVersion
  17. return ( 'Listbox in OREXX v1.00, 1999-06-08 (C) Antal Koos');
  18. /*-------------------------------------*/
  19. ::METHOD String /* returns the last selected item number */
  20. expose LD. item.
  21.         i=LD.SItem;
  22. Return item.i;
  23. /*-------------------------------------*/
  24. ::METHOD Init
  25. expose LD. item. selected. /* LD. = Listbox Descriptor */
  26.         use arg list., nlines, x, y, width
  27. /* list.0 = the number of item strings */
  28. /* nlines = the number of the visible lines */
  29. /* x, y =  upper left coordinate         */
  30. /* width = the displayed length of item strings */
  31.         
  32.         if var('list.1')=0 then do
  33.            item.0=2;
  34.            item.1='The listbox is not initialized!';
  35.            item.2='Use the ~SetList method!';
  36.         end
  37.            else item.= list.~copy;
  38.         if var('nlines')=0 then nlines= min( item.0, 3);
  39.         if var('x')=0 then x=1;
  40.         if var('y')=0 then y=1;
  41.         if var('width')=0 then do
  42.            mx=length( item.1);      
  43.            do i=2 to item.0
  44.                 l=length( item.i)
  45.                 if mx<l then mx=l;
  46.            end /* do */
  47.         width= mx;
  48.         end /* do */
  49.         
  50.  
  51.         LD.SItem=1;         /* SItem - Selected Item */ 
  52.         LD.PrevSItem=0;      
  53.         LD.FDItem=1;       /* FDItem - First Displayed Item */ 
  54.         LD.PrevFDItem=0;
  55.         LD.ilength= width;
  56.         LD.vlines= nlines;  /* number of visible lines */
  57.         LD.row= y; LD.col= x;
  58.         LD.MSelection=.false; /* multiply selection disabled */
  59.         LD.MSKey=d2c(32);     /* default selection key: space */
  60.         LD.MSFoundLast=0;
  61.  
  62.         selected.=.false;
  63.  
  64. Return;
  65. /*-------------------------------------*/
  66. ::METHOD SetMulSelection
  67. expose LD.
  68.         use arg flag, key
  69.         if flag=.true then LD.MSelection=.true
  70.         else if flag=.false then LD.MSelection=.false;
  71.         if var('key')\=0 then LD.MSkey=key;
  72. Return;        
  73. /*-------------------------------------*/
  74. ::METHOD GetFirstSelected
  75. expose LD. item. selected.
  76.         LD.MSFoundLast=0;
  77. Return Self~GetNextSelected;
  78. /*-------------------------------------*/
  79. ::METHOD GetNextSelected
  80. expose LD. item. selected.
  81.         found.index=0;
  82.         do i=LD.MSFoundLast+1 to item.0
  83.            if selected.i then do
  84.                 found.index= i;
  85.                 found.str= item.i;
  86.                 LD.MSFoundLast=i;
  87.                 Return found.
  88.            end /* do */
  89.         end /* do */
  90. Return found.;
  91.  
  92. /*-------------------------------------*/
  93. ::METHOD SetCorner
  94. expose LD.
  95.         use arg x, y
  96.         LD.row= y; LD.col= x;
  97. Return;
  98. /*-------------------------------------*/
  99. ::METHOD SetList
  100. expose LD. item.
  101.         use arg list., width
  102.         if var('width')=0 then Self~Init( list., LD.vlines, LD.col, LD.row)
  103.          else Self~Init( list., LD.vlines, LD.col, LD.row, width); 
  104. Return;
  105. /*-------------------------------------*/
  106. ::METHOD GetList
  107. expose item.
  108. Return item.~copy;
  109. /*-------------------------------------*/
  110. ::METHOD SetWidth
  111. expose LD. item.
  112.         use arg width
  113.         LD.ilength= width;
  114. /*        do i=1 to item.0
  115.            item.i= left( item.i, LD.ilength);
  116.         end */
  117. Return;
  118. /*-------------------------------------*/
  119. ::METHOD SetHeight
  120. expose LD. item.
  121.         use arg h
  122.         if h<1 | h>item.0 then LD.vlines=item.0
  123.         else LD.vlines=h;
  124. Return;
  125. /*-------------------------------------*/
  126. ::METHOD Execute
  127. /* return: .true if Enter pressed; .false if Esc pressed. */
  128. expose LD. item. ufunc. selected.
  129.  
  130.         k_Enter=d2c(13);   k_Esc=d2c(27);     k_Up=d2c(72);
  131.         k_Down=d2c(80);    k_PGUp=d2c(73);    k_PGDown=d2c(81);
  132.         k_Home=d2c(71);    k_End=d2c(79);     k_CtrlPgUp=d2c(132);
  133.         k_CtrlPgDown=d2c(118);
  134.  
  135.         Call SysCurState('OFF');
  136.         Self~Refresh;
  137.         DO FOREVER
  138.                 pkey= Self~GetKey;
  139.                 LD.PrevSItem= LD.SItem; 
  140.                 LD.PrevFDItem= LD.FDItem;
  141.                 if pkey=k_Enter then do
  142.                         /* in single selection mode: selected one item by Enter */ 
  143.                         if \LD.MSelection then do 
  144.                                 t=LD.SItem;
  145.                                 selected.t=.true;
  146.                         end;
  147.                         Leave;
  148.                 end;
  149.                 if pkey=k_Esc then do /* cancel by user */
  150.                         selected.=.false;
  151.                         Leave;
  152.                 end;
  153.                 if LD.MSelection & LD.MSkey=pkey then do /* Multiply selection? */
  154.                         index=LD.SItem;
  155.                         if selected.index then selected.index=.false
  156.                         else selected.index=.true;
  157.                         Self~Refresh;
  158.                         Iterate;
  159.                 end;
  160.                 /* calling user function */
  161.                 if var('ufunc.pkey') then do
  162.                         parse value SysCurPos() with row col /* save cursor */
  163.                         if Self~UserFunction( ufunc.pkey) then Self~Refresh;
  164.                         Call SysCurPos row, col; /* restore cursor */
  165.                         Iterate;
  166.                 end /* do */
  167.                 
  168.                 if length(pkey)=2 then do
  169.                    key= right(pkey,1);
  170.                    select
  171.                      when key= k_Up then do 
  172.                         LD.SItem= max(1, LD.SItem-1); 
  173.                         if LD.SItem<LD.FDItem then LD.FDItem=LD.SItem;
  174.                      end /* do */
  175.                      when key=k_Down then do
  176.                         LD.SItem= min( LD.SItem +1, item.0);
  177.                         if LD.SItem>=LD.FDItem+LD.vlines then LD.FDItem=LD.FDItem+1;
  178.                      end
  179.                      when key=k_PGUp then do
  180.                         LD.SItem= max( 1, LD.SItem-LD.vlines);
  181.                         if LD.SItem<LD.FDItem then LD.FDItem=LD.SItem;
  182.                      end
  183.                      when key=k_PGDown then do
  184.                         LD.SItem= min(LD.SItem+LD.vlines, item.0);
  185.                         if LD.SItem>=LD.FDItem+LD.vlines then LD.FDItem=LD.SItem;
  186.                         if (item.0-LD.FDItem)<LD.vlines then LD.FDItem=item.0-LD.vlines+1;
  187.                      end
  188.                      when key=k_CtrlPgUp then do 
  189.                         LD.SItem= 1; LD.FDItem=1;
  190.                      end /* do */
  191.                      when key=k_CtrlPgDown then do
  192.                         LD.SItem= item.0; 
  193.                         LD.FDItem= max( 1, item.0 -LD.vlines+1);
  194.                      end /* do */
  195.                      when key=k_Home then LD.SItem= LD.FDItem;
  196.                      when key=k_End then LD.SItem= min( item.0, LD.FDItem+LD.vlines-1);
  197.                    otherwise Iterate;
  198.                    end;  /* select */
  199.                    Self~Show;
  200.                 end;
  201.         END /* forever */
  202.         Call SysCurState('ON'); Call SysCurPos 0,0; 
  203.  
  204. if pkey=k_Enter then return .true;
  205. Return .false;
  206.  
  207. /*---------------------------------------------*/
  208. ::METHOD Refresh
  209.         expose LD.
  210.         LD.PrevFDItem=0; /* forcing 'show' to redisplay */
  211.         Self~Show;
  212. return;
  213. /*---------------------------------------------*/
  214. ::METHOD GetKey
  215.  key=SysGetKey('NOECHO');
  216.  if key=d2c(0) | key=d2c(224) then key=key||SysGetKey('NOECHO');
  217. return key;
  218. /*---------------------------------------------*/
  219.  
  220. ::METHOD Show
  221.  expose LD. item. selected.
  222.  pointer='->';
  223.  mulselchar='+';
  224.  empty_pointer='  ';
  225.  more='...';
  226.  no_more='   ';
  227.  
  228.         y=LD.row;
  229.  
  230.         if LD.PrevFDItem = LD.FDItem then do
  231.            if LD.PrevSItem = LD.SItem then return;
  232.            Call SysCurPos y+1 + LD.PrevSItem - LD.FDItem, LD.col;
  233.            say empty_pointer;
  234.            Call SysCurPos y+1 + LD.SItem - LD.FDItem, LD.col;
  235.            say pointer;
  236.            return; 
  237.         end;
  238.  
  239.         Call SysCurPos y, LD.col;
  240.         if LD.FDItem>1 then say more
  241.          else say no_more;
  242.  
  243.         y=y+1;
  244.         DO i= LD.FDItem to (LD.FDItem + LD.vlines -1)
  245.            Call SysCurPos y, LD.col; 
  246.            ms='';
  247.            if LD.MSelection then ms=' ';
  248.            IF i<=item.0 then do
  249.                 if LD.Mselection & selected.i then ms=mulselchar;
  250.                 if i=LD.SItem then say pointer||ms||left( item.i, LD.ilength);
  251.                 else say empty_pointer||ms||left( item.i, LD.ilength); 
  252.            END 
  253.            ELSE say ms||left(' ',LD.ilength+2);
  254.            y=y+1;
  255.         END;
  256.  
  257.         Call SysCurPos y, LD.col;
  258.         if (LD.FDItem + LD.vlines -1)<item.0 then say more
  259.           else say no_more;
  260.  
  261. Return;
  262.  
  263. /*-------------------------------------*/
  264. ::METHOD SetDefaultItem
  265.         expose LD. item.
  266.         use arg itemno;
  267.  
  268.         if itemno<1 | itemno>item.0 then return .false;
  269.         LD.SItem= itemno;
  270.         LD.FDItem= itemno - LD.vlines%2;
  271.         if LD.FDItem<1 then LD.FDItem=1;
  272.         if (item.0 - LD.FDItem)<LD.vlines then LD.FDItem= item.0 - LD.vlines+1;
  273.         return .true;
  274. /*-------------------------------------*/
  275. ::METHOD SetUserFunc
  276.         expose ufunc.
  277.         use arg key, !instr
  278.  
  279.         ufunc.key= !instr;
  280.  
  281. return;
  282. /*-------------------------------------*/
  283. ::METHOD UnSetUserFunc
  284.         expose ufunc.
  285.         use arg key
  286.  
  287.         drop ufunc.key;
  288.  
  289. return;
  290. /*-------------------------------------*/
  291. ::METHOD UserFunction
  292.         expose LD. item.
  293.         use arg !instr;
  294.  
  295.         Interpret !instr
  296.         
  297. if refresh=.true then return .true;
  298. return .false;
  299. /*-------------------------------------*/
  300. /* (Very) simple sort */
  301. ::METHOD Sort
  302. expose item.
  303.         if item.0 = 1 then Return;
  304.  
  305.         top=item.0;
  306.         do while top>1
  307.            m=item.1; indx=1;
  308.            do i= 2 to top
  309.                 if m < item.i then do
  310.                         m= item.i; 
  311.                         indx= i;
  312.                 end /* do */
  313.            end;
  314.            tmp= item.top;
  315.            item.top= m;
  316.            item.indx= tmp;
  317.            top= top-1;
  318.         end /* do */
  319. Return;
  320.