home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / MISC / SRC / INSTALL / ENTRY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-02  |  7.2 KB  |  328 lines

  1. #include <ctype.h>
  2. #include <slang/slang.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. #include "newt.h"
  7. #include "newt_pr.h"
  8.  
  9. #include "log.h"
  10.  
  11. struct entry {
  12.     int flags;
  13.     char * buf;
  14.     char ** resultPtr;
  15.     int bufAlloced;
  16.     int bufUsed;        /* amount of the buffer that's been used */
  17.     int cursorPosition;     /* cursor *in the string* on on screen */
  18.     int firstChar;        /* first character position being shown */
  19. };
  20.  
  21. static void entryDraw(newtComponent co);
  22. static void entryDestroy(newtComponent co);
  23. static struct eventResult entryEvent(struct newtComponent * co, 
  24.                          struct event ev);
  25.  
  26. static struct eventResult entryHandleKey(struct newtComponent * co, int key);
  27.  
  28. static struct componentOps entryOps = {
  29.     entryDraw,
  30.     entryEvent,
  31.     entryDestroy,
  32. } ;
  33.  
  34. void newtEntrySet(newtComponent co, char * value, int cursorAtEnd) {
  35.     struct entry * en = co->data;
  36.  
  37.     if ((strlen(value) + 1) > en->bufAlloced) {
  38.     free(en->buf);
  39.     en->bufAlloced = strlen(value) + 1;
  40.     en->buf = malloc(en->bufAlloced);
  41.     *en->resultPtr = en->buf;
  42.     }
  43.     memset(en->buf, 0, en->bufAlloced);        /* clear the buffer */
  44.     strcpy(en->buf, value);
  45.     en->bufUsed = strlen(value);
  46.     en->firstChar = 0;
  47.     if (cursorAtEnd)
  48.     en->cursorPosition = en->bufUsed;
  49.     else
  50.     en->cursorPosition = 0;
  51.  
  52.     entryDraw(co);
  53. } ;
  54.  
  55. newtComponent newtEntry(int left, int top, char * initialValue, int width,
  56.             char ** resultPtr, int flags) {
  57.     newtComponent co;
  58.     struct entry * en;
  59.  
  60.     logMessage("creating Entry flags = %d", flags);
  61.  
  62.     co = malloc(sizeof(*co));
  63.     en = malloc(sizeof(struct entry));
  64.     co->data = en;
  65.  
  66.     co->top = top;
  67.     co->left = left;
  68.     co->height = 1;
  69.     co->width = width;
  70.     co->callback = NULL;
  71.  
  72.     if (!(en->flags & NEWT_ENTRY_DISABLED))
  73.     co->takesFocus = 1;
  74.     else
  75.     co->takesFocus = 0;
  76.  
  77.     co->ops = &entryOps;
  78.  
  79.     en->flags = flags;
  80.     en->cursorPosition = 0;
  81.     en->firstChar = 0;
  82.     en->bufUsed = 0;
  83.     en->bufAlloced = width + 1;
  84.  
  85.     if (initialValue && strlen(initialValue) > width) {
  86.     en->bufAlloced = strlen(initialValue) + 1;
  87.     }
  88.     en->buf = malloc(en->bufAlloced);
  89.     *resultPtr = en->buf;
  90.     en->resultPtr = resultPtr;
  91.   
  92.     memset(en->buf, 0, en->bufAlloced);
  93.     if (initialValue) {
  94.     strcpy(en->buf, initialValue);
  95.     en->bufUsed = strlen(initialValue);
  96.     en->cursorPosition = en->bufUsed;
  97.     }
  98.  
  99.     return co;
  100. }
  101.  
  102. static void entryDraw(newtComponent co) {
  103.     struct entry * en = co->data;
  104.     int i;
  105.     char * chptr;
  106.     int len;
  107.  
  108.     if (co->top == -1) return;
  109.  
  110.     if (en->flags & NEWT_ENTRY_DISABLED) 
  111.     SLsmg_set_color(NEWT_COLORSET_DISENTRY);
  112.     else
  113.     SLsmg_set_color(NEWT_COLORSET_ENTRY);
  114.  
  115.     if (en->flags & NEWT_ENTRY_HIDDEN) {
  116.     newtGotorc(co->top, co->left);
  117.     for (i = 0; i < co->width; i++)
  118.         SLsmg_write_char('_');
  119.     newtGotorc(co->top, co->left);
  120.  
  121.     return;
  122.     }
  123.  
  124.     newtGotorc(co->top, co->left);
  125.  
  126.     if (en->cursorPosition < en->firstChar) {
  127.     /* scroll to the left */
  128.     en->firstChar = en->cursorPosition;
  129.     } else if ((en->firstChar + co->width) <= en->cursorPosition) {
  130.     /* scroll to the right */
  131.     en->firstChar = en->cursorPosition - co->width + 1;
  132.     }
  133.  
  134.     chptr = en->buf + en->firstChar;
  135.     len = strlen(chptr);
  136.  
  137.     if (len <= co->width) {
  138.     i = len;
  139.     SLsmg_write_string(chptr);
  140.     while (i < co->width) {
  141.         SLsmg_write_char('_');
  142.         i++;
  143.     }
  144.     } else {
  145.     SLsmg_write_nstring(chptr, co->width);
  146.     }
  147.  
  148.     if (en->flags & NEWT_ENTRY_HIDDEN)
  149.     newtGotorc(co->top, co->left);
  150.     else
  151.     newtGotorc(co->top, co->left + (en->cursorPosition - en->firstChar));
  152. }
  153.  
  154. void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense) {
  155.     struct entry * en = co->data;
  156.     int row, col;
  157.  
  158.     en->flags = newtSetFlags(en->flags, flags, sense);
  159.  
  160.     if (!(en->flags & NEWT_ENTRY_DISABLED))
  161.     co->takesFocus = 1;
  162.     else
  163.     co->takesFocus = 0;
  164.  
  165.     newtGetrc(&row, &col);
  166.     entryDraw(co);
  167.     newtGotorc(row, col);
  168. }
  169.  
  170. static void entryDestroy(newtComponent co) {
  171.     struct entry * en = co->data;
  172.  
  173.     free(en->buf);
  174.     free(en);
  175.     free(co);
  176. }
  177.  
  178. static struct eventResult entryEvent(struct newtComponent * co, 
  179.                      struct event ev) {
  180.     struct entry * en = co->data;
  181.     struct eventResult er;
  182.  
  183.     if (ev.when == EV_NORMAL) {
  184.     switch (ev.event) {
  185.       case EV_FOCUS:
  186.         /*SLtt_set_cursor_visibility(0);*/
  187.         if (en->flags & NEWT_ENTRY_HIDDEN)
  188.         newtGotorc(co->top, co->left);
  189.         else
  190.         newtGotorc(co->top, co->left + 
  191.                 (en->cursorPosition - en->firstChar));
  192.         er.result = ER_SWALLOWED;
  193.         break;
  194.  
  195.       case EV_UNFOCUS:
  196.         /*SLtt_set_cursor_visibility(1);*/
  197.         newtGotorc(0, 0);
  198.         er.result = ER_SWALLOWED;
  199.         if (co->callback) co->callback(co, co->callbackData);
  200.         break;
  201.  
  202.       case EV_KEYPRESS:
  203.         er = entryHandleKey(co, ev.u.key);
  204.         break;
  205.     }
  206.     } else
  207.     er.result = ER_IGNORED;
  208.  
  209.     return er;
  210. }
  211.  
  212. static struct eventResult entryHandleKey(struct newtComponent * co, int key) {
  213.     struct entry * en = co->data;
  214.     struct eventResult er;
  215.     char * chptr, * insPoint;
  216.  
  217.     er.result = ER_SWALLOWED;
  218.     switch (key) {
  219.       case '\r':                /* Return */
  220.     if (en->flags & NEWT_ENTRY_RETURNEXIT) {
  221.         er.result = ER_EXITFORM;
  222.     } else {
  223.         er.result = ER_NEXTCOMP;
  224.     }
  225.     break;
  226.  
  227.       case '\001':                /* ^A */
  228.       case NEWT_KEY_HOME:
  229.     en->cursorPosition = 0;
  230.     break;
  231.  
  232.       case '\005':                /* ^E */
  233.       case NEWT_KEY_END:
  234.     en->cursorPosition = en->bufUsed;
  235.     break;
  236.  
  237.       case '\013':                /* ^K */
  238.     en->bufUsed = en->cursorPosition;
  239.     memset(en->buf + en->bufUsed, 0, en->bufAlloced - en->bufUsed);
  240.     break;
  241.  
  242.       case '\002':                /* ^B */
  243.       case NEWT_KEY_LEFT:
  244.     if (en->cursorPosition)
  245.         en->cursorPosition--;
  246.     break;
  247.  
  248.       case '\004':
  249.       case NEWT_KEY_DELETE:
  250.     chptr = en->buf + en->cursorPosition;
  251.     if (*chptr) {
  252.         chptr++;
  253.         while (*chptr) {
  254.         *(chptr - 1) = *chptr;
  255.         chptr++;
  256.         }
  257.         *(chptr - 1) = '\0';
  258.         en->bufUsed--;
  259.     }
  260.     break;
  261.  
  262.       case NEWT_KEY_BKSPC:
  263.     if (en->cursorPosition) {
  264.         /* if this isn't true, there's nothing to erase */
  265.         chptr = en->buf + en->cursorPosition;
  266.         en->bufUsed--;
  267.         en->cursorPosition--;
  268.         while (*chptr) {
  269.         *(chptr - 1) = *chptr;
  270.         chptr++;
  271.         }
  272.         *(chptr - 1) = '\0';
  273.     }
  274.     break;
  275.  
  276.       case '\006':                /* ^B */
  277.       case NEWT_KEY_RIGHT:
  278.     if (en->cursorPosition < en->bufUsed)
  279.         en->cursorPosition++;
  280.     break;
  281.  
  282.       default:
  283.     if ((key >= 0x20 && key <= 0x7e) || (key >= 0xa0 && key <= 0xff)) {
  284.         if (!(en->flags & NEWT_ENTRY_SCROLL) && en->bufUsed == co->width) {
  285.         SLtt_beep();
  286.         break;
  287.         } 
  288.     
  289.         if ((en->bufUsed + 1) == en->bufAlloced) {
  290.         en->bufAlloced += 20;
  291.         en->buf = realloc(en->buf, en->bufAlloced);
  292.         *en->resultPtr = en->buf;
  293.         memset(en->buf + en->bufUsed + 1, 0, 20);
  294.         }
  295.  
  296.         if (en->cursorPosition == en->bufUsed) {
  297.         en->bufUsed++;
  298.         } else {
  299.         /* insert the new character */
  300.  
  301.         /* chptr is the last character in the string */
  302.         chptr = (en->buf + en->bufUsed) - 1;
  303.         if ((en->bufUsed + 1) == en->bufAlloced) {
  304.             /* this string fills the buffer, so clip it */
  305.             chptr--;
  306.         } else 
  307.             en->bufUsed++;
  308.  
  309.         insPoint = en->buf + en->cursorPosition;
  310.  
  311.         while (chptr >= insPoint) {
  312.             *(chptr + 1) = *chptr;
  313.             chptr--;
  314.         }
  315.  
  316.         }
  317.         
  318.         en->buf[en->cursorPosition++] = key;
  319.     } else {
  320.         er.result = ER_IGNORED;
  321.     }
  322.     } 
  323.  
  324.     entryDraw(co);
  325.  
  326.     return er;
  327. }
  328.