home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / s / s001 / 1.ddi / PFC / SRC / PLEDT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-09  |  14.0 KB  |  587 lines

  1. /* 88-05-07 Jahns    kbnec() -> GETCHR()                */
  2. /* 01-Aug-1988 Jahns    plitmhilit() with ATROFS            */
  3. /* 01-Aug-1988 Jahns    pledt() select with char            */
  4. /* 02-Aug-1988 Jahns    pledt() f_end included                */
  5. /* 16-Sep-1988 Jahns    MOUSES() included                */
  6. /* 20-Sep-1988 Jahns    SET_MOUSE_WND() included            */
  7. /* 88-10-04 Vogt N.    ATROFS replaced by TASK->PTERM->ATROFS        */
  8. /* 88-10-20 Jahns    if F1 return 0x21                */
  9. /* 89-06-13 Jahns    return all functionkey's                        */
  10. /* 89-11-23 Vogt N.    GETCHR() --> GET_CHR()                */
  11.  
  12.  
  13.  
  14. /* (c) 1985, Phoenix Computer Products Corp. and Novum Organum, Inc. */
  15. /***
  16. * name :    plist - create an instance of a pick-list object.
  17. *
  18. * synopsis:    plist(h_wnd,get_fnc,ttl)
  19. *        h_wnd    - the window in which the pick-list appears
  20. *        ttl    - a string which will appear on the first line
  21. *              of the list.    this line will not be scrolled.
  22. *              if no comment is desired, then pass a NULLPTR.
  23. *        get_fnc - address of function which will be called to get
  24. *              formatted elements which will appear in the
  25. *              list.
  26. *
  27. * description:    create a new object and set its attributes.
  28. *
  29. * returns:    handle of newly created object.
  30. *
  31. * name :    plrls - release an instance of a pick-list object.
  32. *
  33. * synopsis:    plrls(h_pl)
  34. *        h_pl    handle to a pick list object.
  35. *
  36. * name :    pllstkey - return key which terminated input.
  37. *        pldsp - display a set of elements in a pick-list
  38. *        pledt - let the user choose an element in the list.
  39. *
  40. * synopsis:    pldsp(h_pl)
  41. *        h_pl    handle to pick-list to be displayed.
  42. *
  43. *        pledt(h_pl, &chc, str)
  44. *        h_pl    handle to pick-list
  45. *        chc    the number of the element in the list
  46. *                which the user chose.
  47. *        str    string buffer in which the text of the
  48. *                chosen element will be placed.
  49. *                if you do not wish text returned, make
  50. *                this argument a NULLPTR.
  51. *
  52. *        key = pllstkey()
  53. *        <type,code> - the type code of the key which caused input
  54. *            to terminate
  55. *
  56. * description:    pick-lists are for allowing the user to chose from a list
  57. *        of items which is longer than the number of lines in
  58. *        a given screen area.  the cursor keys allow the user
  59. *        to scroll the elements of the list in and out of the
  60. *        screen area.
  61. *
  62. * returns:    pldsp() return RC_FAIL if no elements were displayed.
  63. *            othewise SUCCEED is returned.
  64. *        pllstkey() returns a word containing the <type,code> pair
  65. *            of the key which caused input to terminate.
  66. *        pledt() return
  67. *            RC_FAIL - no elements in list.
  68. *            RC_ESC - user pressed <ESC>
  69. *            RC_SPECIAL - user pressed special key, e.g. function key.
  70. *            RC_ENTER - the user pressed the <enter> key.
  71. *
  72. * (C) novum organum, inc. 1985
  73. *
  74. ***/
  75. #include "compiler.h"
  76.  
  77. #define f_new
  78.  
  79. #include "cptenv2.h"
  80. #include "cptpdf.h"
  81.  
  82. extern struct CEPT_ENV *TASK;
  83.  
  84. #include "psys.h"
  85.  
  86.  
  87.  
  88. static plitmhilit (short row, short f_hilit)
  89. {
  90.   if (f_hilit) vstsetinvrs();
  91.   _vdspa(row, 0, vidncols(), VD_CURSTAT);
  92.   if (f_hilit) vstsetnorml();
  93. }
  94.  
  95.  
  96.  
  97.  
  98. GLOBAL HDL plist (HDL h_wnd, PFI get_fnc, char8 *ttl)
  99. {
  100.   HDL       h_pl;
  101.   char8    *memgive();
  102.  
  103.   h_pl = (HDL) memgive(sizeof(PICKLIST));
  104.  
  105.   H_PL->tag       = ADT_PL;
  106.   H_PL->h_wnd       = h_wnd;
  107.   H_PL->ttl       = ttl;
  108.   H_PL->get_fnc    = get_fnc;
  109.   H_PL->fst_on_scr = 0;
  110.   H_PL->csr_off    = 0;
  111.   return (h_pl);
  112.  
  113. }    /* plist */
  114.  
  115.  
  116.  
  117. GLOBAL HDL plrls(FAST HDL h_pl)
  118. {
  119.   HDL h_wnd;
  120.  
  121.   adtverify (h_pl, ADT_PL);   /* verify that this is a pick-list object.*/
  122.   H_PL->tag = DEAD_TAG;       /* zap tag.                  */
  123.   h_wnd = H_PL->h_wnd;
  124.   memtake(h_pl);          /* zap pick-list.               */
  125.  
  126.   return (h_wnd);
  127. }
  128.  
  129.  
  130. GLOBAL void plsetchc(FAST HDL h_pl, int fst_on_scr, int chc)
  131.  
  132. {
  133.   adtverify (h_pl, ADT_PL);
  134.   if (chc < 0) chc = 0;
  135.   if (fst_on_scr > chc) fst_on_scr = chc;
  136.   else
  137.     if (fst_on_scr < 0) fst_on_scr = 0;
  138.   H_PL->fst_on_scr = fst_on_scr;
  139.   H_PL->csr_off    = chc - fst_on_scr;
  140.  
  141. }    /* plsetchc */
  142.  
  143.  
  144.  
  145. static short fillplist( HDL   h_pl,
  146.             short row,
  147.             short lst_row,
  148.             char8 *buf,
  149.             short nxt_itm )
  150. {
  151.   register short  n_dspd, ncols;
  152.  
  153.   n_dspd = 0;
  154.   ncols  = vidncols() + 1;
  155.  
  156.   while (row < lst_row)
  157.   {
  158.     /* if another string is returned, then add to window.        */
  159.     /* but if at end-of-list (RC_FAIL), then stop on this line.        */
  160.     if ((*H_PL->get_fnc)(nxt_itm, buf, ncols) == RC_FAIL)
  161.       break;
  162.     vdsplns(row++, 0, ncols, buf);
  163.     nxt_itm++;            /* actual number displayed in list        */
  164.     n_dspd++;
  165.   }
  166.   while(row < lst_row)
  167.     vdsplns(row++, 0, ncols, "");
  168.   return (n_dspd);
  169.  
  170. }    /* fillplist */
  171.  
  172.  
  173.  
  174. static short _pldsp (HDL h_pl, short nrows, char8 *buf, short *pfst_row)
  175. {
  176.   register short  max_itms, n_on_scr;
  177.  
  178.   wndtotop(H_PL->h_wnd);
  179.   max_itms = nrows;
  180.  
  181.   if  (H_PL->ttl)
  182.   {
  183.     vdspls(0, 0, H_PL->ttl);
  184.     max_itms--;
  185.     *pfst_row = 1;
  186.   }
  187.   else
  188.     *pfst_row = 0;
  189.     /* fill the box with as many choices a possible, starting with FST_ON_SCR*/
  190.  
  191.   if  (H_PL->csr_off >= max_itms)
  192.   {
  193.     H_PL->fst_on_scr -= (H_PL->csr_off - max_itms + 1);
  194.     if (H_PL->fst_on_scr < 0)
  195.       H_PL->fst_on_scr = 0;
  196.   }
  197.  
  198.   FOREVER
  199.   {
  200.     n_on_scr = fillplist(h_pl, *pfst_row, nrows, buf, H_PL->fst_on_scr);
  201.  
  202.     if (H_PL->csr_off >= n_on_scr)       /* make certain cursor is over  */
  203.       H_PL->csr_off = n_on_scr - 1;       /* a choice in the window.       */
  204.     if    (n_on_scr > 0)
  205.        break;
  206.     /* nothing was successfully put in the pick-list.  however maybe*/
  207.     /* we are past the end of the list.  if we are not at the first*/
  208.     /* (zero'th) element of the list, let's try from the beginning  */
  209.     /*  if we are already there, then just quit.            */
  210.     H_PL->csr_off = 0;
  211.     if (H_PL->fst_on_scr > 0)
  212.       H_PL->fst_on_scr = 0;
  213.     else
  214.       break;      /* already at begin.    nothing in list.      */
  215.   }
  216.  
  217.   return (n_on_scr);
  218.  
  219. }    /* _pldsp */
  220.  
  221.  
  222.  
  223.  
  224. GLOBAL short pldsp(HDL h_pl)
  225. {
  226.   register short   rc, prv_attr;
  227.   short        fst_row;
  228.   HDL           prv_pl, prv_wnd, wndsetactv();
  229.   char8        s[81];
  230.  
  231.   adtverify (h_pl, ADT_PL);          /* verify that really a pick-list*/
  232.   rc        = RC_SUCCESS;
  233.   prv_wnd   = wndsetactv(H_PL->h_wnd);
  234.   prv_attr  = vstsetattr(VA_NORMAL);
  235.   if (_pldsp (h_pl, vidnrows(), s, &fst_row) > 0)
  236.     plitmhilit(fst_row + H_PL->csr_off, NO);
  237.   else
  238.     rc = RC_FAIL;
  239.   vstsetattr(prv_attr);
  240.   wndsetactv(prv_wnd);
  241.  
  242.   return(rc);
  243.  
  244. }    /* pldsp */
  245.  
  246.  
  247.  
  248. static char8 TEST_CH(char8 *s)
  249. {
  250.   register short I;
  251.  
  252.   for (I = 0; I < vidncols() + 1; ++I)
  253.   {
  254.     if (s[I] != SP) break;
  255.   }
  256.   return(s[I]);
  257.  
  258. }    /*TEST_CH */
  259.  
  260.  
  261.  
  262. static BOOLEAN MORE(HDL h_pl, char CH, char *s)
  263. {
  264.   register short i, cnt, ncols;
  265.  
  266.   ncols = vidncols() + 1;
  267.   cnt = 0;
  268.   i = -1;
  269.   for(;;)
  270.   {
  271.     if((*H_PL->get_fnc)(++i, s, ncols) == RC_FAIL) break;
  272.     if (CH == TEST_CH(s)) ++cnt;
  273.     if (cnt > 1) break;
  274.   }
  275.   return ((cnt > 1) ? TRUE : FALSE);
  276.  
  277. }    /* MORE */
  278.  
  279.  
  280.  
  281. GLOBAL short pledt (HDL h_pl, short *pchc)
  282. {
  283.   register short i, k, row, rc;
  284.   short      csr_off,  csr_typ, chc, nrows, fst_row, max_itms;
  285.   short      ncols, fst_on_scr, n_on_scr, prv_attr, f_fill;
  286.   HDL         prv_pl, prv_wnd, wndsetactv();
  287.   short      pos, pos_sav;
  288.   BOOLEAN     cont, more, TERM;
  289.   short      CH, CHR;
  290.   short      MROW, MCOL;
  291.   WND         *act_wnd;
  292.   short      min_col, min_row;
  293.   short      max_col, max_row;
  294.   short      min_c, max_c, min_r, max_r;
  295.   short      func_key;
  296.   struct pc_kbd  *PKBD;
  297.   char8      s[81];
  298.   short      savdev;
  299.   PFI         get_fnc;
  300.  
  301.   savdev  = SETCRT(CONDEV);
  302.  
  303.   PKBD      = TASK->PKBD;
  304.  
  305.   adtverify (h_pl, ADT_PL);          /* verify that really a pick-list*/
  306.  
  307.   get_fnc   = H_PL->get_fnc;
  308.   prv_wnd   = wndsetactv(H_PL->h_wnd);
  309.   act_wnd   = (WND *) H_PL->h_wnd;
  310.   ncols     = vidncols() + 1;
  311.   prv_attr  = vstsetattr(VA_NORMAL);
  312.   nrows     = vidnrows();
  313.   csr_typ   = vidcsrtyp(CSR_HIDDEN);
  314.  
  315.   rc = RC_FAIL;
  316.  
  317.   if  ((n_on_scr = _pldsp (h_pl, nrows, s, &fst_row)) > 0)
  318.   {
  319.     rc           = RC_LOOP;
  320.     max_itms   = nrows - fst_row;
  321.     csr_off    = H_PL->csr_off;
  322.     fst_on_scr = H_PL->fst_on_scr;
  323.     f_fill     = NO;
  324.   }
  325.  
  326.   if (PKBD->XMOUSE)
  327.   {
  328.     MOUSE_CLR();
  329.     min_c = min_col = act_wnd->pcol;
  330.     max_c = max_col = act_wnd->pcol + act_wnd->pncols + 1;
  331.     min_r = min_row = act_wnd->prow;
  332.     max_r = max_row = act_wnd->prow + act_wnd->pnrows + 1;
  333.     SET_MOUSE_WND(&min_c, &max_c, &min_r, &max_r);
  334.   }
  335.  
  336.   while(rc == RC_LOOP)        /* fails without executing loop if list is empty.*/
  337.   {
  338.     plitmhilit(fst_row + csr_off, YES);         /*display current choice.*/
  339.  
  340.  
  341.     for (;;)
  342.     {
  343.       chc = fst_on_scr + csr_off;
  344.  
  345.       if (CHKKBD())
  346.       {
  347.     if (PKBD->XMOUSE && PKBD->MOUSE_ON) MOUSEOFF();
  348.     CH = GET_KBD();
  349.     if (CH) break;
  350.       }
  351.  
  352.       if (PKBD->XMOUSE)
  353.       {
  354.     MOUSE_POS(min_row + fst_row + csr_off, min_col + 1);
  355.  
  356.     TERM = TRUE;
  357.  
  358.     switch(MOUSE_INP(&MROW, &MCOL))
  359.     {
  360.       case 0 : TERM = FALSE;
  361.            break;
  362.  
  363.       case 2 :
  364.            CH = 0x0121;
  365.            WRITE_BTC(CH);
  366.            break;
  367.  
  368.       case 3 :
  369.            CH = ESC;
  370.            WRITE_BTC(CH);
  371.            break;
  372.  
  373.       case 1 :
  374.            if (MROW == min_row || MROW == max_row)
  375.            {
  376.              CH = (MROW == min_row) ? f_prev : f_next;
  377.              WRITE_BTC(CH);
  378.              break;
  379.            }
  380.            if (MCOL == max_col)
  381.              { CH = f_end; WRITE_BTC(CH); break; }
  382.            if (MCOL == min_col)
  383.              { CH = APH; WRITE_BTC(CH); break; }
  384.  
  385.            row = MROW - min_row - 1;
  386.  
  387.            if (row < n_on_scr)
  388.            {
  389.              MOUSEOFF();            /* mouse cursor off     */
  390.              plitmhilit(fst_row + csr_off, NO);
  391.              csr_off = row;
  392.              plitmhilit(fst_row + csr_off, YES);
  393.              MOUSE_POS(min_row + fst_row + csr_off, min_col + 1);
  394.              pos = fst_on_scr + csr_off;
  395.              if (chc == pos)
  396.              {
  397.                CH = CR;
  398.                WRITE_BTC(CH);
  399.                break;
  400.              }
  401.              else
  402.              {
  403.                if (TASK->BATCHPR)
  404.                {
  405.              (*get_fnc)(pos, s, ncols);
  406.              CHR = TEST_CH(s);
  407.              WRITE_BTC(APH);
  408.              k = 0;
  409.              i = max_itms - 1;
  410.              for(;;)
  411.              {
  412.                if ((pos - k) >= i)
  413.                {
  414.                  WRITE_BTC(f_next);
  415.                  k += i;
  416.                }
  417.                else break;
  418.              }
  419.              if (k) ++k;
  420.              for(i = k; i <= pos; ++i)
  421.              {
  422.                (*get_fnc)(i, s, ncols);
  423.                if (TEST_CH(s) == CHR) WRITE_BTC(CHR);
  424.              }
  425.                }
  426.              }
  427.            }    /* if (row < n_on_scr) */
  428.            TERM = FALSE;
  429.            break;
  430.     }
  431.     if (TERM) break;
  432.       }
  433.  
  434.     } /* for (;;)   */
  435.  
  436.     if (PKBD->XMOUSE && PKBD->MOUSE_ON) MOUSEOFF();
  437.  
  438.     func_key = (CH >= f_fun) ? TRUE : FALSE;
  439.  
  440.     plitmhilit(fst_row + csr_off, NO);
  441.  
  442.     switch (CH)
  443.     {
  444.       case ESC      :
  445.             rc = RC_ESC;
  446.             break;
  447.       case CR      :
  448.             rc = RC_ENTER;
  449.             break;
  450.       case SP      :
  451.       case APD      :
  452.             if    (csr_off < n_on_scr - 1)     /* in middle of window? */
  453.             csr_off++;    /* yes, just go to next window line. */
  454.             else      /* at bottom of screen, any more elements? */
  455.             if ((*get_fnc)(fst_on_scr + n_on_scr, s, ncols)!=RC_FAIL)
  456.             {
  457.              /* yes, more elements, so scroll up             */
  458.              /* add new element to bottom of window.         */
  459.               vidareascroll(fst_row, 0, max_itms, ncols, 1);
  460.                          /* put new choice on last line  */
  461.               vdsplns(fst_row + csr_off, 0, ncols, s);
  462.               fst_on_scr++;
  463.             }
  464.             else
  465.             sybeep();
  466.             break;
  467.       case APU      :
  468.             if    (csr_off > 0)          /* in middle of screen?         */
  469.             csr_off--;          /* yes, just move up one line. */
  470.             else
  471.             if    ((fst_on_scr > 0)     /* are we in middle of list?   */
  472.              &&              /* got previous element ok?    */
  473.              ((*get_fnc)(fst_on_scr - 1, s, ncols) != RC_FAIL))
  474.             {
  475.               vidareascroll(fst_row, 0, max_itms, ncols, -1);
  476.               fst_on_scr--;
  477.               n_on_scr++;
  478.               if  (n_on_scr > max_itms)
  479.               n_on_scr = max_itms;
  480.                          /* put new elm on first line. */
  481.               vdsplns(fst_row, 0, ncols, s);
  482.             }
  483.             else
  484.             sybeep();
  485.             break;
  486.       case APH      :
  487.             fst_on_scr = 0;            /*move to begin of list. */
  488.             csr_off    = 0;            /* then fill window.     */
  489.             f_fill     = YES;
  490.             break;
  491.       case f_prev :                    /* Pg-Up */
  492.             if    (fst_on_scr > 0)   /* if not at first element of list*/
  493.             {               /* then move up NLNS-1 and refill */
  494.               i       = MIN(max_itms - 1, fst_on_scr);
  495.               fst_on_scr -= i; /* compute first now on screen, number*/
  496.               f_fill      = YES;
  497.             }
  498.             else         /* move to first element in window. */
  499.             if    (csr_off > 0) csr_off = 0;
  500.             else sybeep();
  501.             break;
  502.       case f_next :                    /* Pg-Dn */
  503.             fst_on_scr += (n_on_scr - 1); /*last elm now on first line*/
  504.             f_fill = YES;
  505.             break;
  506.       case f_end  :
  507.             pos = fst_on_scr + csr_off;
  508.             while((*get_fnc)(++pos, s, ncols) != RC_FAIL);
  509.             fst_on_scr = pos - max_itms;
  510.             if (fst_on_scr < 0) fst_on_scr = 0;
  511.             f_fill = YES;
  512.             break;
  513.  
  514.       default      :
  515.             if (func_key)
  516.             {
  517.               rc = CH;
  518.               break;
  519.             }
  520.  
  521.             CH        = toupper(CH);
  522.             pos     = fst_on_scr + csr_off;
  523.             pos_sav = pos;
  524.             cont    = TRUE;
  525.             more    = MORE(h_pl, CH, s);
  526.  
  527.             for (;;)
  528.             {
  529.               if((*get_fnc)(++pos, s, ncols) != RC_FAIL)
  530.               {
  531.             if (CH == toupper(TEST_CH(s)))
  532.             {
  533.               if (! TASK->BATCH && ! TASK->BATCHPR &&
  534.                 ! more && pos == pos_sav)
  535.                  rc = RC_ENTER;
  536.               i = pos - fst_on_scr;
  537.               if (i > 0 && i < n_on_scr)
  538.               {
  539.                 csr_off = i;
  540.                 break;
  541.               }
  542.               fst_on_scr = pos;
  543.               csr_off    = 0;
  544.               f_fill     = YES;
  545.               break;
  546.             }
  547.               }
  548.               else
  549.               {
  550.             if (cont)
  551.             {
  552.               pos  = -1;
  553.               cont = FALSE;
  554.             }
  555.             else {
  556.               sybeep();
  557.               break;
  558.             }
  559.               }
  560.             }
  561.             break;
  562.     }    /* switch */
  563.  
  564.     if    (f_fill)
  565.     {
  566.       n_on_scr = fillplist(h_pl, fst_row, nrows, s, fst_on_scr);
  567.       if  (csr_off >= n_on_scr)
  568.       csr_off = n_on_scr-1;
  569.       f_fill = NO;
  570.     }
  571.   }    /* while(rc==RC_LOOP) */
  572.  
  573.   vidcsrtyp(csr_typ);
  574.   chc           = fst_on_scr + csr_off;
  575.   H_PL->fst_on_scr = fst_on_scr;    /* save the num. of first in window */
  576.   H_PL->csr_off    = csr_off;        /* save offset of cursor in window. */
  577.   *pchc        = chc;        /* return choice number.        */
  578.   vstsetattr(prv_attr);
  579.   wndsetactv(prv_wnd);
  580.  
  581.   if (PKBD->XMOUSE) SET_MOUSE_WND(&min_c, &max_c, &min_r, &max_r);
  582.  
  583.   SETCRT(savdev);
  584.  
  585.   return (rc);
  586. }
  587.