widget.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 952 行 · 第 1/2 页
C
952 行
/* Print a COMMAND widget label */void printcommand(wdgt) WIDGET *wdgt;{ mvwaddstr(wdgt->wndw,1,1,wdgt->label); (void) wrefresh(wdgt->wndw);}/* THESE ROUTINES GET AND REACT TO A USERS INPUT FROM THE KEYBOARD *//* Loop forever, calling widget callback functions when activated */void interact(){ register int ch, indx; void int_quit(), jumpback(); for (;;) {/* Get a character input, and set the interrupt jump vector */ (void) setjmp(env); (void) signal(SIGINT, int_quit); move(0,0); (void) wrefresh(Text); refresh(); ch = getchar(); if (isupper(ch)) ch = tolower(ch); (void) signal(SIGINT, jumpback); /* Allow the user to refresh the entire screen, with a CTRL-L */ if (ch == '\014') { redraw(); scrollbar('\0'); continue; }/* Search through the current widgets for one matching that required */ command = ch; indx = findactiveinput(ch); if (indx >= 0) docallback(indx); ch = 0; }}/* Find a callback 'ch' from the currently active set of widgets */int findactiveinput(ch) char ch;{ register int indx; register WIDGET *wdgts; if (ch > 'z' || ch < 'a') { switch (ch) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ch = '*'; break; case '[': case ']': ch = '%'; break; case '?': ch = 'h'; break; } }/* See whether the 'ch' exists in the currently active widgets */ wdgts = activelist.widgets[activelist.count - 1]; indx = getwidgetindex(wdgts, ch); if (indx >= 0) return(indx); /* If not, check the previously active widgets, if possible */ if (activelist.count <= 1) return(-1); indx = getwidgetindex(activelist.widgets[activelist.count - 2], ch); if (indx >= 0) { killwidgets(activelist.widgets[activelist.count - 1]); return(indx); } return(-1);}void docallback(indx) char indx;{ WIDGET *wdgts; activeindex(indx); wdgts = activelist.widgets[activelist.count - 1]; switch (wdgts[indx].type) { case DIALOG: if (command >= '1' && command <= '9') get_listed_object (command, &wdgts[indx]); else { dialog(&wdgts[indx]); (*wdgts[indx].callfn)(); } break; case TOGGLE: toggle(&wdgts[indx]); (*wdgts[indx].callfn)(); break; case SCROLLBAR : scrollbar(command); break; default: (*wdgts[indx].callfn)(); break; }}/* THESE ROUTINES SEARCH THE ACTIVE WIDGET SET FOR ONE SPECIFIED WIDGET *//* Find a widget based on the call-back character */WIDGET *getwidget(wdgts, callch) int callch; WIDGET wdgts[];{ register int indx; indx = getwidgetindex(wdgts, callch); if (indx >= 0) return(&(wdgts[indx])); return((WIDGET *)NULL);}int getwidgetindex(wdgts, callch) int callch; WIDGET wdgts[];{ register int cnt = 0; while (wdgts[cnt].type != FINISH) { if (callch == wdgts[cnt].callch) break; ++cnt; } if (wdgts[cnt].type != FINISH) return(cnt); return(-1);}/* THESE ROUTINES MANIPULATE THE DIALOG WIDGETS */void dialog(wdgt) WIDGET *wdgt;{ register int i, length, labellen, maxlen; register char ch, *endptr, *showptr; register char *blanks; labellen = strlen(wdgt->label); /* The length of the prompt string */ length = strlen(wdgt->dstr); /* The length of the current string */ maxlen = wdgt->wdth - 4 - labellen; /* The maximum length of shown str */ blanks = malloc((unsigned)(maxlen + 2)); for (i=0; i<maxlen; i++) blanks[i] = ' '; blanks[i] = '\0'; endptr = &(wdgt->dstr[length]); /* The next character pos'n to fill */ *endptr = '\0'; if (length > maxlen) showptr = &(wdgt->dstr[length - maxlen]); else showptr = wdgt->dstr; (void) mvwprintw(wdgt->wndw, 1, 1, "%s%c%s", wdgt->label, (length > maxlen)? '<' : ' ', showptr); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ while ((ch = getchar() & 127) != '\n' && ch != '\r' && ch != '\f') { if (ch == '\014') { /* Allow for redrawing */ redraw(); continue; } if (ch == '\b' || ch == 127) { /* Delete a character, with wrapping */ if (length == 0) continue; *(--endptr) = '\0'; /* Make the last character NULL */ if (showptr > wdgt->dstr) /* We have parts of the string hidden */ --showptr; --length; if (length < maxlen) { /* Only need to erase one character */ (void) waddstr(wdgt->wndw,"\b \b"); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ continue; } /* We'll have to erase everything */ (void) wprintw(wdgt->wndw, "\r|%s%c%s \b", wdgt->label, (length <= maxlen)? ' ' : '<', showptr); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ continue; } if (ch == 21) { /* ^U to delete the entire line of text */ length = 0; endptr = wdgt->dstr; *endptr = '\0'; showptr = wdgt->dstr; (void) wprintw(wdgt->wndw, "\r|%s %s\r|%s ", wdgt->label, blanks, wdgt->label); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ continue; } /* Otherwise, add the character if there is room and it ain't a control code */ if (length == 1024 || ch < 32) continue; if (length == wdgt->dstrlen){ *endptr++ = ch; *endptr = '\0'; setdialogstr(wdgt, showptr, wdgt->dstrlen);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ continue; } *endptr++ = ch; *endptr = '\0'; if (++length <= maxlen) { /* Just add this character to the end */ (void) waddch(wdgt->wndw, ch); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ continue; } ++showptr; (void) wprintw(wdgt->wndw, "\r|%s<%s", wdgt->label, showptr); (void) wrefresh(wdgt->wndw);#ifdef QUICKREFRESH doupdate ();#endif /* QUICKREFRESH */ } free(blanks);}void setdialogstr(wdgt, dstr, maxlen) char *dstr; WIDGET *wdgt;int maxlen ;{ if (wdgt->type != DIALOG) return; wdgt->dstr = dstr; wdgt->dstrlen = maxlen;}int getdialogstr(wdgt, str) /* 'str' must be long enough... */ char str[]; WIDGET *wdgt;{ if (wdgt->type != DIALOG || wdgt->dstr == (char *)NULL) return(FALSE); (void) strcpy(str, wdgt->dstr); return(TRUE);}/* THESE ROUTINES MANIPULATE THE TOGGLE WIDGETS */void toggle(wdgt) WIDGET *wdgt;{ WIDGET *vwdgt; int av_indx; if (wdgt->tvalues == (char **)NULL) return; if (wdgt == getwidget(currwidgets, 't')) { typetoggled = 1; vwdgt = getwidget(currwidgets, 's'); (void) strcpy(filtvalue[wdgt->tindx], vwdgt->dstr); av_indx = 0; while (av_typeindx[av_indx] != wdgt->tindx && av_typeindx[av_indx] >= 0) av_indx++; if (av_typeindx[av_indx] == wdgt->tindx) av_indx++; if (av_typeindx[av_indx] < 0) av_indx = 0; wdgt->tindx = av_typeindx[av_indx]; (void) strcpy(vwdgt->dstr, filtvalue[wdgt->tindx]); typeindx = wdgt->tindx; printdialog(vwdgt); } printtoggle(wdgt);}void settogglstrs(wdgt, togglstrs, togglindx) int togglindx; char **togglstrs; WIDGET *wdgt;{ if (wdgt->type != TOGGLE) return; wdgt->tvalues = togglstrs; wdgt->tindx = togglindx;}int settogglindx(wdgt, indx) int indx; WIDGET *wdgt;{ int i; if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) return(FALSE); for (i=0; i<indx; i++) if (wdgt->tvalues[i] == (char *)NULL) break; if (i != indx) /* There ain't that many toggle strings */ return(FALSE); wdgt->tindx = indx; return(TRUE);}int gettogglindx(wdgt) WIDGET *wdgt;{ if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) return(-1); return(wdgt->tindx);}int gettogglstr(wdgt, str) /* 'str' must be long enough... */ WIDGET *wdgt; char str[];{ if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) return(FALSE); (void) strcpy(str, wdgt->tvalues[wdgt->tindx]); return(TRUE);}/* THESE ROUTINES MANIPULATE THE LABEL WIDGETS */void setlabel(wdgt, label) WIDGET *wdgt; char *label;{ wdgt->label = label;}void getlabel(wdgt, label) /* 'label' must be long enough... */ WIDGET *wdgt; char label[];{ (void) strcpy(label, wdgt->label);}/* MISCELLANEOUS FUNCTIONS *//* Try to locate the bottom of the last set of widgets displayed */int lowesty(){ register int cnt = 0; register WIDGET *wdgts; if (activelist.count <= 0) return(0); wdgts = activelist.widgets[activelist.count - 1]; while (wdgts[cnt].type != FINISH) ++cnt; if (cnt == 0) return(0); return((wdgts[cnt-1].y) + WDGTHGHT);}/* This satisfies the generalised printing structure *//* ARGSUSED */void wprint(here, fmt, a,b,c,d,e,f,g,h,i,j) WINDOW *here; char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j;{ (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); (void) wrefresh(Text);}/* This can be called as a way for an application to print text *//* VARARGS1 */void tprint(fmt, a,b,c,d,e,f,g,h,i,j) char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j;{ (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); (void) wrefresh(Text);}void xprint(fmt) char *fmt;{ (void) wprintw(Text, "%s", fmt);}void xprintint(fmt, a) char *fmt; int a;{ (void) wprintw(Text,fmt, a);}void cleartext(){#ifndef QUICKREFRESH clearok (Text,TRUE);#endif /* QUICKREFRESH */ (void) wclear (Text);}/* Jump back to the interact function only on an interrupt */void jumpback(){ (void) waddstr(Text,"\n*** Interrupted ***\n"); (void) wrefresh(Text); longjmp(env, TRUE);}/* This is used as a declaration, when no function callback is required */void nullfn(){}/* This is used by widgets that just want to kill the current level */void quitfn(){ (void) wclear(Text); (void) wrefresh(Text); killwidgets(activelist.widgets[activelist.count - 1]);}void endwidgets(){ move(LINES-1, 0); refresh(); endwin();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?