home *** CD-ROM | disk | FTP | other *** search
- /*
-
- pcled.cpp
- 7-30-91
- Line Edit for the IBM PC Text Modes.
-
- Copyright 1991
- John W. Small
- All rights reserved
- Use freely but acknowledge authorship and copyright.
-
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072 USA
-
- Voice: (703) 759-3838
- CIS: 73757,2233
-
- */
-
-
- #include <ctype.h>
- #include <string.h>
- #include <conio.h>
- #include <pckey.hpp>
- #include <pcled.hpp>
-
-
-
- Palette LineEdit::defaultP = {
-
- 0, /* monochrome or color */
-
- svideo(WHITE,BLACK), svideo(BLACK,LIGHTGRAY),
- svideo(BLACK,LIGHTGRAY), svideo(BLUE,LIGHTGRAY),
- svideo(DARKGRAY,LIGHTGRAY), svideo(WHITE,BLUE)
- };
-
-
- int LineEdit::edit(char *response, int sizeofResponse,
- int flen, int x, int y, const char *pref,
- const char *prompt, TFvaliD validate)
- {
- struct text_info ti;
- CursorShape cursor;
- int maxlen, insmode, rlen, i, fscol, c, erase, j;
- int owscroll;
- int w, h;
-
- if ((maxlen = sizeofResponse - 1) < 1 || flen < 1)
- return 0;
- gettextinfo(&ti);
- w = ti.winright - ti.winleft + 1;
- h = ti.winbottom - ti.wintop + 1;
- if (x < 1 || y < 1) {
- x = wherex();
- y = wherey();
- }
- else if (x + (prompt?strlen(prompt)+2:0)
- >= w - 1 || y > h)
- return 0;
- // two extra spaces required for arrows
-
- cursor.saveOrig();
- owscroll = _wscroll;
- _wscroll = 0;
- mappalette(P);
-
- insmode = 1;
- cursor.normal();
- gotoxy(x,y);
-
- if (prompt) {
- mapvideo(PROMPT,P);
- cprintf("%s: ",prompt);
- }
- if (pref) {
- i = strlen(pref);
- strncpy(response,pref,maxlen);
- if (i > maxlen)
- i = maxlen;
- }
- else
- i = 0;
- response[rlen = i] = '\0'; /* i & fscol are zero biased */
-
-
- x = wherex(); y = wherey();
-
- /* leave two extra spaces for backward and forward arrows */
- if (flen > w-x-1)
- flen = w-x-1;
-
- if (i > flen)
- fscol = i + 1 - flen;
- else
- fscol = 0;
-
- erase = 1;
- mapvideo(RESPONSE,P);
-
- while (1) {
- cursor.off();
- gotoxy(x,y);
- if (erase) {
- putch(fscol?'\021':' ');
- mapvideo(PREFERENCE,P);
- j = cprintf("%-.*s",flen,&response[fscol]);
- mapvideo(RESPONSE,P);
- cprintf("%*.s",flen-j,"");
- putch((fscol+flen < rlen)?'\020':' ');
-
- }
- else
- cprintf("%c%-*.*s%c",(fscol?'\021':' '),
- flen,flen,&response[fscol],
- ((fscol+flen<rlen)?'\020':' '));
- /* leave extra space for backward arrow */
- gotoxy(x+i-fscol+1,y);
- cursor.on();
- c = PCK.getkey();
- switch (c) {
- case -Home:
- fscol = i = 0;
- break;
- case -EndKey:
- i = rlen;
- if (i >= fscol + flen)
- fscol = i+1 - flen;
- break;
- case CtrlS:
- case -LArr:
- if (i)
- if (--i < fscol)
- fscol = i;
- break;
- case CtrlA:
- case -CtrlLArr:
- while (i && !isalnum(response[i-1])) i--;
- while (i && isalnum(response[i-1])) i--;
- if (i < fscol)
- fscol = i;
- break;
- case CtrlD:
- case -RArr:
- if (i < rlen)
- if (++i >= fscol + flen)
- fscol = i+1 - flen;
- break;
- case CtrlF:
- case -CtrlRArr:
- while (i < rlen && isalnum(response[i])) i++;
- while (i < rlen && !isalnum(response[i])) i++;
- if (i >= fscol + flen)
- fscol = i+1 - flen;
- break;
- case -UpArr:
- case -DnArr:
- if (pref) {
- i = strlen(pref);
- strncpy(response,pref,maxlen);
- if (i > maxlen)
- i = maxlen;
- response[rlen = i] = '\0';
- /* i & fscol are zero biased */
- if (i > flen)
- fscol = i + 1 - flen;
- else
- fscol = 0;
- erase = 1;
- continue;
- }
- break;
- case CtrlV:
- case -InsKey:
- if (insmode) {
- cursor.block();
- insmode = 0;
- }
- else {
- cursor.normal();
- insmode = 1;
- }
- break;
- case -DelKey:
- if (response[i] && rlen) {
- strcpy(&response[i],&response[i+1]);
- rlen--;
- }
- break;
- case CR:
- if (validate)
- if (!(*validate)(response,maxlen)) {
- putch('\a');
- erase = 1;
- continue;
- }
- gotoxy(x,y);
- cprintf(" %-*.*s ",flen,flen,response);
- gotoxy(x+1,y);
- _wscroll = owscroll;
- textattr(ti.attribute);
- cursor.restoreOrig();
- return 1;
- case ESC:
- response[i=0] = '\0';
- gotoxy(x,y);
- cprintf(" %-*.*s ",flen,flen,response);
- gotoxy(x+1,y);
- _wscroll = owscroll;
- textattr(ti.attribute);
- cursor.restoreOrig();
- return 0;
- case BACKSP: /* CtrlH */
- if (i) {
- strcpy(&response[i-1],&response[i]);
- rlen--;
- if (--i < fscol)
- fscol = i;
- else if (fscol)
- fscol--;
- }
- break;
- case CtrlT:
- if (i == rlen) break;
- if (isalnum(response[i]))
- while (isalnum(response[i]) && i < rlen) {
- strcpy(&response[i],&response[i+1]);
- rlen--;
- }
- else if (!isspace(response[i])) {
- strcpy(&response[i],&response[i+1]);
- rlen--;
- }
- while (isspace(response[i]) && i < rlen) {
- strcpy(&response[i],&response[i+1]);
- rlen--;
- }
- break;
- case CtrlY:
- response[rlen = fscol = i = 0] = '\0';
- break;
- case CtrlQ:
- cursor.off();
- gotoxy(x,y);
- blinkvideo();
- putch('Q');
- unblinkvideo();
- gotoxy(x+i-fscol+1,y);
- cursor.on();
- switch (PCK.getkey()) {
- case CtrlY:
- case 'Y':
- case 'y':
- response[rlen = i] = '\0';
- break;
- case CtrlS:
- case 'S':
- case 's':
- fscol = i = 0;
- break;
- case CtrlD:
- case 'D':
- case 'd':
- i = rlen;
- if (i >= fscol + flen)
- fscol = i+1 - flen;
- break;
- default:
- putch('\a');
- break;
- }
- break;
- case TAB: // tabs not allowed
- putch('\a');
- break;
- default:
- if (isprint(c) && rlen <= maxlen) {
- if (erase) {
- response[rlen = fscol = i = 0] = '\0';
- gotoxy(x,y);
- cprintf(" %-*.*s ",flen,flen,response);
- }
- if (insmode || i >= rlen) {
- if (rlen == maxlen) {
- putch('\a');
- break;
- }
- for (j = rlen; j >= i; j--)
- response[j+1] = response[j];
- rlen++;
- }
- response[i] = c;
- if (i < rlen)
- if (++i >= fscol + flen)
- fscol = i+1 - flen;
- }
- else
- putch('\a');
- break;
- }
- erase = 0;
- }
- }
-
- int LineEditWindow::edit(char *response, int sizeofResponse,
- int flen, int x, int y, const char *pref,
- const char *prompt, TFvaliD validate)
- {
- struct text_info ti;
-
- if (sizeofResponse < 2 || flen < 1)
- return 0;
- if (flen > sizeofResponse)
- flen = sizeofResponse;
- gettextinfo(&ti);
- if (x < 1 || y < 1 ||
- x + flen + 3 > ti.screenwidth ||
- y + 3 > ti.screenheight) {
- x = ti.screenwidth/2 - flen/2 - 2;
- y = ti.screenheight/2 - 1;
- }
- if (!window(x,y,x+3+flen,y+2))
- return 0;
- if (prompt)
- putTitle(prompt);
- int ok = LineEdit::edit(response,sizeofResponse,
- flen,1,1,pref,(char *)0,validate);
- close();
- return ok;
- }
-