/** * iloop.c -- nsf subroutine **/ #include #include #include "nsf.h" /** * mesg() -- message to user. **/ void mesg(s) char *s; { int i; if (s != NULL) beep(); if (s == NULL) s="Next Field: TAB 1st Field: HOME Help: ESC End: RETURN"; move(LINES-1,0); clrtoeol(); i = (COLS - strlen(s))/2; move(LINES-1,i); if (use_uline) attroff(A_UNDERLINE); addstr(s); if (use_uline) attron(A_UNDERLINE); move(fld[cfld].y,fld[cfld].x+ccol); } /** * backspace() **/ void backspace(){ struct INFLD *p; int y,x,c,i; p = &fld[cfld]; y = p->y; x = p->x+ccol; if (ccol < 1){ cfld--; if (cfld < 0) cfld = nfld - 1; ccol = 0; return; } if (ccol == (p->len - 1)){ c = mvinch(y,x); if ((c & 0xff) != ' '){ addch(' '); return; } } for(i = ccol ; i < fld[cfld].len ; ++i){ x = fld[cfld].x + i; c = mvinch(y,x); mvaddch(y,x-1,c); } mvaddch(y,fld[cfld].x+fld[cfld].len-1,' '); ccol--; } /** * field_get() get field value if it's ok. **/ int field_get(){ struct INFLD *p; int i; char buf[BUFSIZ],*s; p = &fld[cfld]; for(i = 0 ; i < p->len ; i++){ move (p->y,p->x + i); buf[i] = (char)inch(); } for(i = p->len - 1; i >= 0 ; i--) if (buf[i] != ' ') break; buf[++i] = '\0'; if (!(p->attr & SF_SELECT) && p->attr & (SF_DIGITS|SF_REAL)){ s = &buf[0]; while (*s == ' ') ++s; if (*s == '+' || *s == '-') ++s; while(*s >= '0' && *s <= '9') ++s; if (p->attr & SF_REAL){ if (*s == '.') ++s; while (*s >= '0' && *s <= '9') ++s; } if (*s != '\0'){ if (p->attr & SF_REAL) mesg("MUST BE NUMERIC"); else mesg("MUST BE INTEGER NUMBER."); return 0; } } strcpy(p->inp,buf); return 1; } /** * end_ok() **/ int end_ok(){ ccol = 0; for(cfld = 0 ; cfld < nfld ; ++cfld){ if (!field_get()) return 0; if ((fld[cfld].attr & SF_FORCE) && fld[cfld].inp[0] == '\0'){ mesg("YOU CAN NOT OMIT THIS ITEM."); return 0; } } return 1; } /** * field_move() move cfld and ccol **/ void field_move(c) int c; { int i,x,y,yy; if (c == KEY_HOME){ cfld = ccol = 0; move(fld[0].y,fld[0].x); return; } x = fld[cfld].x + ccol; y = fld[cfld].y; if (c == KEY_DOWN || c == '\012'){ for(i = (cfld + 1) % nfld;;i = (i+1)%nfld) if ((yy = fld[i].y) != y) break; for(i++;i < nfld && fld[i].y == yy;i++) if (fld[i].x > x) break; i--; }else if (c == KEY_UP){ for(i = (cfld + nfld - 1) % nfld;;i = (i+nfld-1)%nfld) if ((yy = fld[i].y) != y) break; for(i--;i >= 0 && fld[i].y == yy;i--) if (fld[i].x+fld[i].len < x) break; i++; }else if (c == '\t'){ i = cfld + 1; if (i >= nfld) i = 0; }else if (c == '\r'){ for(i = cfld ; i < nfld ; ++i) if (fld[i].y > y) break; } if (i >= nfld || i < 0){ beep(); move(fld[cfld].y,fld[cfld].x+ccol); return; } cfld = i; ccol = 0; move(fld[cfld].y,fld[cfld].x+ccol); } /** * next_option() display next option. **/ void next_option(){ struct INFLD *p; int i; field_get(); p = &fld[cfld]; for(i = 0 ; i < p->len ; ++i) move(p->y,p->x+i),addch(' '); for(i = 0 ; i < p->nopt ; ++i) if (!strcmp(p->inp,p->opt[i])) break; if (++i >= p->nopt) i = 0; move(p->y,p->x); addstr(p->opt[i]); move(p->y,p->x); } void iloop(){ int i,c; char buf[80]; struct INFLD *p; if (cfld < 0) cfld = 0; if (cfld > nfld) cfld = nfld - 1; ccol = 0; if (use_uline) attron(A_UNDERLINE); for(i = 0 ; i < nfld ; ++i){ p = &fld[i]; move(p->y,p->x); addstr(p->def); } move(fld[cfld].y,fld[cfld].x); leaveok(stdscr,FALSE); if (initmesg[0] != '\0') mesg(initmesg); else mesg(NULL); while (1){ move(fld[cfld].y,fld[cfld].x+ccol); refresh(); c = getch(); c &= 0x1ff; mesg(NULL); if (c == '\r'){ if (!field_get()) continue; if (end_ok()) break; }else if (c == KEY_DOWN || c == KEY_UP || c == KEY_HOME || c == '\t'|| c == '\012'){ if (!field_get()) continue; field_move(c); }else if (c == KEY_LEFT){ if (ccol > 0) ccol--; else{ cfld--; if (cfld < 0) cfld = nfld - 1; ccol = fld[cfld].len - 1; } }else if (c == KEY_RIGHT){ if (ccol < (fld[cfld].len - 1)) ccol++; else{ cfld++; if (cfld >= nfld) cfld = 0; ccol = 0; } }else if (c == '\033'){ /* ESC */ if (fld[cfld].help[0] == '\0') mesg(NULL); else mesg(fld[cfld].help); }else if (fld[cfld].attr & SF_SELECT){ if (c != ' ') mesg("HIT SPACE KEY TO CHANGE"); else next_option(); }else if (c == KEY_BACKSPACE || c == '\010'){ backspace(); }else if (c >= ' ' && c <= '}'){ if (fld[cfld].attr & SF_UCASE) c = toupper(c); else if (fld[cfld].attr & SF_LCASE) c = tolower(c); addch(c); if ((ccol+1) >= fld[cfld].len){ if (!field_get()) continue; if (fld[cfld].attr & SF_ASCEND) field_move('\t'); }else{ ccol++; } }else if (c == '\014'){ clearok(stdscr,TRUE); }else{ beep(); if (debug_on){ sprintf(buf,"0x%x (\\%o) comes",c,c); mesg(buf); } } } }