home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / MENUPUTB.C < prev    next >
C/C++ Source or Header  |  1990-12-15  |  6KB  |  253 lines

  1. /*
  2.     menuputb.c
  3.  
  4.     % menu_putTB, menu_ClearTB, menu_setcursor
  5.  
  6.     C-scape 3.2
  7.     Copyright (c) 1986, 1987, 1988 by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     ---------------------
  12.     04/22/89 jdc    fixed attr problem found by (NAME)?
  13.     05/23/89 jdc    made tb_setcursor menu_setcursor
  14.                     speed up for no wrapping case
  15.     06/05/89 jdc    added if (text != NULL) text += len, in overwrite
  16.     07/27/89 jdc    put menu_SetDirty in menu_ClearTB
  17.     08/04/89 jdc    played with tb->set_cursor
  18.     08/09/89 jdc    made len and count longs
  19.  
  20.     11/10/89 jdc    added color optimization
  21.     12/12/89 jmd    made colors bytes
  22.      3/28/90 jmd    ansi-fied
  23.     10/28/90 jdc    fixed boolean/int ret conflict
  24.     12/15/90 jdc    fixed color problem
  25. */
  26.  
  27. #include "menu.h"
  28.  
  29. OSTATIC bblock_type  bblock_end(bblock_type b);
  30.  
  31. static bblock_type bblock_end(bblock_type b)
  32. {
  33.     while (b->next != NULL) {
  34.         b = b->next;
  35.     }
  36.     return(b);
  37. }
  38.  
  39. boolean menu_putTB(menu_type menu, int row, int col, char *text, char chr, unsigned slen, byte color, byte old_color, int mode)
  40. /*
  41.     takes DISPLAYED (expanded) position.
  42.     mode == TB_COLOR, TB_SAMECOLOR
  43. */
  44. {
  45.     tb_type tb;
  46.     int ins, oldrow, spaces, color_newline = 0;
  47.     long count, len;
  48.     int asize;
  49.     bblock_type b = NULL, ib;
  50.     boolean ret = TRUE;    
  51.  
  52.     cs_Assert(menu_Ok(menu), CS_TB_P_TB, 0);
  53.     cs_Assert(row >= 0 && col >= 0, CS_TB_P_OOR, 0);
  54.     tb = menu_GetTextbuf(menu);
  55.     asize = tb->bbc->asize;
  56.  
  57.     if ((oldrow = tb_FindLine(tb, row)) <= 0) { /* row past the end */
  58.  
  59.         count = (long)(row + oldrow - 1);    /* count number of new rows */
  60.  
  61.         if (!tb->limit || tb->size + count + 1L <= tb->max_size) {
  62.  
  63.             bbc_Set(tb->bbc, (long)tb->len, '\n', count, FALSE);
  64.             if ((mode == TB_COLOR || mode == 3) 
  65.             && !bbc_Attr(tb->bbc, (long)tb->len, old_color, count)) {
  66.                     return(FALSE);
  67.             }
  68.  
  69.             if (mode == TB_COLOR && color != old_color) {
  70.                 tb->bbc->asize = 1;
  71.                 b = bblock_open(tb->bbc, 1L, bblock_end(tb->bbc->b), color);
  72.             }
  73.             if (bbc_Set(tb->bbc, (long)tb->len+count, '\n', 1L, FALSE) == 0L) {
  74.                 return(FALSE);
  75.             }
  76.             tb->size += count + 1L;
  77.         }
  78.         oldrow = -oldrow;
  79.     }
  80.     else {
  81.         oldrow = tb_GetRow(tb);
  82.     }
  83.     count = 0L;
  84.     tb_FindPosition(tb, row, col);                /* set cursor */
  85.     spaces = col - (tb->exp_len - tb->nend);    /* tb->exp_len includes '\n' */
  86.     len = (long)(tb->len - tb->nend);            /* tb->len includes '\n' */
  87.     col = (int)(tb->cursor - tb->offset);        /* unexpand col */
  88.  
  89.     if (spaces > 0) {                            /* past end of line */
  90.  
  91.         if (tb->limit && tb->size + spaces > tb->max_size) {
  92.             return(FALSE);
  93.         }
  94.         if (bbc_work(tb->bbc, (long)len, NULL, ' ', (long)spaces, BBC_INSERT) == 0L) {
  95.             return(FALSE);
  96.         }
  97.           if ((mode == TB_COLOR || mode == 3)
  98.         && !bbc_Attr(tb->bbc, len, old_color, (long)spaces)) {
  99.             ret = FALSE;
  100.         }
  101.         tb->size += spaces;
  102.         len += (long)spaces;
  103.         col += spaces;
  104.     }
  105.     if (tb->insert == TED_INSERT || spaces >= 0) {
  106.         ins = TRUE;
  107.         if ((long)col >= len && tb->nend && TB_COLOR) {
  108.             color_newline = 1;
  109.         }
  110.     }
  111.     else if ((len = len - (long)col) <= (long)slen) { /* overwrite till line end */
  112.         if (tb->nend && TB_COLOR) {
  113.             color_newline = 1;
  114.         }
  115.         if (len > 0L) {
  116.             if ((len = bbc_work(tb->bbc, (long)col, text, chr, len, FALSE)) == 0) {
  117.                 ret = FALSE;
  118.             }
  119.             if ((mode == TB_COLOR || mode == 3)
  120.             && !bbc_Attr(tb->bbc, (long)col, color, len + (long)color_newline)) {
  121.                 ret = FALSE;
  122.             }
  123.             col += (int)len;
  124.             if (text != NULL) {
  125.                 text += (int)len;
  126.             }
  127.             slen -= (unsigned int)len;
  128.         }
  129.         ins = TRUE;
  130.     }
  131.     else {
  132.         ins = FALSE;
  133.     }
  134.  
  135.     if (slen > 0) {
  136.         if (ins && tb->limit && tb->size + slen > tb->max_size) {
  137.             ret = FALSE;
  138.         }
  139.         else {
  140.             if (bbc_work(tb->bbc, (long)col, text, chr, (long)slen, 
  141.                 (b != NULL && ins) ? BBC_ENDINS:ins) == 0L) {
  142.                 ret = FALSE;
  143.             }
  144.             else {
  145.                 if (ins) {
  146.                     tb->size += slen;
  147.                 }
  148.                 count += slen;
  149.             }
  150.             slen += color_newline;
  151.             if (mode == TB_COLOR || mode == 3) {
  152.                 if (b != NULL) {
  153.                     for (ib = b; ib != NULL; ib = ib->next) {
  154.                         ib->attr = color;
  155.                     }
  156.                 }
  157.                 else if (!bbc_Attr(tb->bbc, (long)col, color, (long)slen)) {
  158.                     ret = FALSE;
  159.                 }
  160.             }
  161.         }
  162.     }
  163.     /* find the cursor position */
  164.     tb->cursor = tb->offset + (long)col + count;
  165.  
  166.     if (tb->width < 32000) {
  167.         /* move back in case of funny wrapping */
  168.         tb_FindLine(tb, (oldrow <= 1) ? 0 : oldrow - 1);
  169.     }
  170.     menu_setcursor(menu);
  171.  
  172.     /* menu_SetDirty(menu, TRUE);  keep track of menu size manually */
  173.     if ((row = tb_GetRow(tb)) > oldrow) {
  174.         if (tb->insert) {
  175.             menu->rowcount += row - oldrow;
  176.         }
  177.         else if (row >= menu->rowcount) {
  178.             menu->rowcount = row + 1;
  179.         }
  180.     }
  181.     tb->bbc->asize = asize;
  182.  
  183.     return(ret);
  184. }
  185.  
  186. menu_type menu_ClearTB(menu_type menu)
  187. {
  188.     bbc_Close((menu_GetTextbuf(menu))->bbc);
  189.  
  190.     tb_setup(menu_GetTextbuf(menu));
  191.  
  192.     menu_SetDirty(menu, TRUE);
  193.  
  194.     return(menu);
  195. }
  196.  
  197. int menu_setcursor(menu_type menu)
  198. /*
  199.     sets hints after adding to textbuffer
  200. */
  201. {
  202.     tb_type tb;
  203.     unsigned int expan, i, count;
  204.     bbpeek_struct bp;
  205.     int dlen, row;
  206.  
  207.     tb = menu->textbuf;
  208.     row = tb_GetRow(tb);
  209.  
  210.     /* move back */
  211.     while ( tb->offset > tb->cursor ) {
  212.         if ( --row < 0 ) {
  213.             tb->cursor = 0;
  214.         }
  215.         tb_FindLine(tb, row);
  216.     }
  217.  
  218.     /* move forward */
  219.     for ( ; tb_FindLine(tb, row) == TRUE; row++ ) {
  220.  
  221.         if ( tb->exp_len > menu->colcount ) {            /* check size */
  222.             menu->colcount = tb->exp_len;
  223.         }
  224.         if ( tb->offset + (long)tb->len > tb->cursor ) { /* position cursor */
  225.             bp.b = tb->bbc->b;
  226.             bp.off = bp.b->off;
  227.             bp.len = (long)tb->len;
  228.             count = (unsigned int)(tb->cursor - tb->offset);
  229.             expan = 0;        
  230.             do {
  231.                 for ( dlen = bbpeek(&bp), i = 0; i < dlen; i++, count-- ) {
  232.  
  233.                     if ( count <= 0 ) {
  234.                         tb->col = expan;
  235.                         return(tb->cursor_set = TRUE);
  236.                     }
  237.                     expan += tb_translate(tb, expan, bp.p + i);
  238.                 }
  239.                 bp.off += dlen;
  240.                 bp.len -= (long)dlen;
  241.  
  242.             } while( dlen > 0 );
  243.         }
  244.     }
  245.     tb->cursor = tb->offset + (long)tb->len - 1L;    /* cursor on last char */
  246.     tb->col = tb->exp_len - 1;
  247.  
  248.     return(tb->cursor_set = FALSE);
  249. }
  250.  
  251.  
  252.  
  253.