widget.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 952 行 · 第 1/2 页
C
952 行
/* widget.c - Provides the screen and widget code */#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/uips/sd/RCS/widget.c,v 9.0 1992/06/16 12:45:08 isode Rel $";#endif/* * $Header: /xtel/isode/isode/others/quipu/uips/sd/RCS/widget.c,v 9.0 1992/06/16 12:45:08 isode Rel $ *//* This file has been modified by Damanjit Mahl @ Brunel University *//* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * *//*****************************************************************************//* File: widget.c/* Author: Paul Sharpe @ GEC Research, Hirst Research Centre./* Date: August 12, 1988./* Function: Provides the screen and widget code./*/* DISCLAIMER:/* This source file is deemed to be public domain: any person may use the/* code in any way, on two simple provisos -/* 1 - That this header remains in this file,/* 2 - It is accepted that neither the author, nor the authors employees/* accept any responsibility for the use, abuse or misuse of the/* contained code./* No guarantee is made by the author to provide maintainance or up-grading/* of this source. However, any adaptations made to this file will be viewed/* at least with interest./*****************************************************************************/#include <ctype.h>#include <stdio.h>#ifdef notanymore /* SYS 5 symbol clashes with curses... */#include <sgtty.h>#endif#include "widget.h"#include <setjmp.h>#include <signal.h>#include "general.h"#if defined(SYS5) || defined (_AIX) /* doupdate() call not in BSD curses */#define QUICKREFRESH#endif#ifdef QUICKREFRESH#define wrefresh(x) wnoutrefresh(x)#ifdef refresh#undef refresh#endif#define refresh doupdate#endif /* QUICKREFRESH */extern char *filtvalue[];extern unsigned int typeindx;extern int *av_typeindx;void get_listed_object(), scrollbar();struct active { int count; WIDGET *widgets[MAXACTIVE]; char lastindex[MAXACTIVE]; WINDOW *text[MAXACTIVE];} activelist;char command;WINDOW *Text;int text_height;jmp_buf env;void initwidgets(){ (void) initscr(); (void) noecho(); (void) crmode(); Text = stdscr; typetoggled = 0; activelist.count = 0;}void textfresh(){ (void) wrefresh (Text);}void setwidgets(thesewdgts, y) int y; WIDGET *thesewdgts;{ currwidgets = thesewdgts; lowy = posnwidgets(thesewdgts, y); Text = newwin(LINES-1-lowy, COLS-3, lowy, 3); text_height = LINES-1-lowy;#ifndef QUICKREFRESH refresh();#endif /* QUICKREFRESH */ (void) scrollok(Text, FALSE); (void) wrefresh(Text); makewidgets(thesewdgts); activewidget(thesewdgts, Text); rfrshwidgets(thesewdgts);}int linec(){ return (int) LINES;}int gety(){ int y,x; getyx(Text, y, x); /* Get rid of lint warning */ x = x + 1; return y + lowy;}/* Determine the positions of the widgets: return the lowest point */int posnwidgets(thesewdgts, starty) int starty; WIDGET thesewdgts[];{ register int cnt = 0, x = 0, hght = WDGTHGHT;/* If no explicit position provided, put on the next level */ if (starty < 0) starty = lowesty();/* Set the position of the widgets, as dynamically as possible */ while (thesewdgts[cnt].type != FINISH) { if (thesewdgts[cnt].type != DUMMY) {/* If the widget is a scrollbar put on a new line */ if (thesewdgts[cnt].type == SCROLLBAR) { starty += WDGTHGHT; hght = LINES - starty; x = 0; } else /* If the initial structure y-value is CRNL, put on a new line */ if (thesewdgts[cnt].y == CRNL) { starty += WDGTHGHT; hght = WDGTHGHT; x = 0; }/* If we ain't got a width, make one based on the type/label-length */ if (thesewdgts[cnt].wdth <= 0) setwdgtwdth(&thesewdgts[cnt], x);/* If the widget won't fit, start a new line of widgets */ if (x + thesewdgts[cnt].wdth > COLS) { starty += WDGTHGHT; x = 0; } thesewdgts[cnt].x = x; thesewdgts[cnt].y = starty; thesewdgts[cnt].hght = hght; x += thesewdgts[cnt].wdth; ++cnt; } else ++cnt; } return(starty);}/* Create the widgets: return the number of widgets */void makewidgets(wdgts) WIDGET wdgts[];{ register int cnt = 0; register WIDGET *wdgt;/* Now try to make, box and label the widget windows */ while (wdgts[cnt].type != FINISH) { if (wdgts[cnt].type != DUMMY) { wdgt = &wdgts[cnt++]; wdgt->wndw = newwin(wdgt->hght,wdgt->wdth,wdgt->y,wdgt->x); boxwdgt(wdgt, '-', '|'); printwdgt(wdgt); } else ++cnt; }}/* Set a widgets width, based on the TYPE of widget and label length */void setwdgtwdth(wdgt, currx) int currx; WIDGET *wdgt;{ char expand; register int len = -1, cnt = -1; if (expand = (wdgt->wdth == EXPAND)) wdgt->wdth = COLS - currx; switch (wdgt->type) { case LABEL: len = strlen(wdgt->label) + 2; if (wdgt->wdth < len) if (expand) wdgt->wdth = COLS; else wdgt->wdth = len; break; case DIALOG: len = strlen(wdgt->label) + 2; if (wdgt->dstrlen > DIALOGLEN) len += DIALOGLEN; else len += wdgt->dstrlen; if (wdgt->wdth < len) { if (expand) wdgt->wdth = COLS; else wdgt->wdth = len; } break; case TOGGLE: if (wdgt->tvalues == (char **)NULL) wdgt->wdth = strlen(wdgt->label) + 2; else { while(wdgt->tvalues[++cnt] != (char *)NULL) if ((int)strlen(wdgt->tvalues[cnt]) > len) len = strlen(wdgt->tvalues[cnt]); wdgt->wdth = strlen(wdgt->label) + len + 2; } break; default: wdgt->wdth = strlen(wdgt->label) + 2; break; }}/* Erase and remove the widgets, decrementing the activelist counter */void killwidgets(thesewdgts) WIDGET *thesewdgts;{ register int cnt = 0; while (thesewdgts[cnt].type != FINISH) if (thesewdgts[cnt].type != DUMMY) { (void) wclear(thesewdgts[cnt].wndw); (void) wrefresh(thesewdgts[cnt++].wndw); } else ++cnt; cnt = 0;#ifndef QUICKREFRESH (void) wclear(Text);#endif /* QUICKREFRESH */ (void) wrefresh(Text); while (thesewdgts[cnt].type != FINISH) if (thesewdgts[cnt].type != DUMMY) delwin(thesewdgts[cnt++].wndw); else ++cnt; delwin(Text); deleteactive(); Text = activelist.text[activelist.count-1]; if (Text != (WINDOW *)NULL) (void) wrefresh(Text);}/* THESE FUNCTIONS MANIPULATE THE ACTIVELIST ARRAY OF WIDGETS *//* This should check that the number of active widgets is not excessive, or * have the activelist really as a linked list. *//* ARGSUSED */void activewidget(wdgts, text) WIDGET wdgts[]; WINDOW *text;{ activelist.widgets[activelist.count] = wdgts; activelist.text[activelist.count] = Text; ++(activelist.count);}void deleteactive(){ if (activelist.count > 0) --(activelist.count);}void activeindex(indx) char indx;{ activelist.lastindex[activelist.count - 1] = indx;}/* Refresh each of the active widgets and the current text window */void redraw(){ register int i;#ifndef QUICKREFRESH clearok(curscr,TRUE);#endif /* QUICKREFRESH */ for (i=0; i<activelist.count; i++) rfrshwidgets(activelist.widgets[i]); (void) wrefresh(Text);}void rfrshwidgets(thesewdgts) WIDGET *thesewdgts;{ int i = 0; while(thesewdgts[i].wndw != (WINDOW *)NULL && thesewdgts[i].type != DUMMY){ touchwin(thesewdgts[i].wndw); (void) wrefresh(thesewdgts[i++].wndw); }}/* Draw a perimeter box around WDGT, with horizontal char XCH etc */void boxwdgt(wdgt, xch, ych) char xch, ych; register WIDGET *wdgt;{ register int x, y; mvwaddch(wdgt->wndw, 0, 0, '.'); for (x = 1; x < wdgt->wdth-1; x++) (void) waddch(wdgt->wndw, xch); (void) waddch(wdgt->wndw, '.'); mvwaddch(wdgt->wndw, 1, 0, ych); for (y = 1; y < wdgt->hght-1; y++) { (void) mvwaddch(wdgt->wndw, y, 0, ych); (void) mvwaddch(wdgt->wndw, y, wdgt->wdth-1, ych); } mvwaddch(wdgt->wndw, wdgt->hght-1, 0, '`'); for (x = 1; x < wdgt->wdth-1; x++) (void) waddch(wdgt->wndw, xch); (void) waddch(wdgt->wndw, '\'');}/* THESE ROUTINES PRINT THE INDIVIDUAL WIDGET BOXES *//* Print a widgets label, dependant on the widget type */void printwdgt(wdgt) WIDGET *wdgt;{ switch(wdgt->type) { case LABEL: printlabel(wdgt); break; case DIALOG: printdialog(wdgt); break; case TOGGLE: printtoggle(wdgt); break; default : printcommand(wdgt); break; }}void printbar(list_size, first, display_num) int list_size, first, display_num;{ WIDGET * wdgt; int cnt, bar_size, bar_pos=0, space_size; for(cnt = 0; currwidgets[cnt].type != SCROLLBAR; cnt++) ; wdgt = &currwidgets[cnt]; (void) wclear(wdgt->wndw); boxwdgt(wdgt, '-', '|'); space_size = wdgt->hght - 4; if(display_num == list_size) { bar_size = space_size; bar_pos = 1; } else { bar_size = (display_num*space_size)/(list_size+1); bar_size = bar_size? bar_size: 1; while(!((list_size*bar_pos)/(first*(space_size+1)))) bar_pos++; } while((bar_size + bar_pos - 1) > space_size) { bar_size--; } for(cnt = 0; cnt < bar_size; cnt++) (void) mvwaddch(wdgt->wndw, cnt+1+bar_pos, 1, '*'); (void) mvwaddch(wdgt->wndw, 1, 1, ']'); (void) mvwaddch(wdgt->wndw, wdgt->hght-2, 1, '['); (void) wrefresh(wdgt->wndw);}/* Print a LABEL widgets label string, dependant on the justification char */void printlabel(wdgt) WIDGET *wdgt;{ register int x, labellen, wdgtlen; labellen = strlen(wdgt->label); wdgtlen = wdgt->wdth - 2; if (labellen > wdgtlen) wdgt->label[wdgtlen] = '\0'; if (wdgt->callch & CENTRE) x = (wdgtlen - labellen)/2; else if (wdgt->callch & LEFT) x = 0; else if (wdgt->callch & RIGHT) x = wdgtlen - labellen; mvwaddstr(wdgt->wndw,1,1+x,wdgt->label); (void) wrefresh(wdgt->wndw);}/* Print a DIALOG widget label: if it don't all fit, show the last part */void printdialog(wdgt) WIDGET *wdgt;{ register int length, maxlen; register char *showptr; (void) wclear(wdgt->wndw); boxwdgt(wdgt, '-', '|'); if (wdgt->dstr != (char *)NULL) { length = strlen(wdgt->dstr); maxlen = wdgt->wdth - 4 - strlen(wdgt->label); 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);}/* Print a TOGGLE widget label, and the current toggle value */void printtoggle(wdgt) WIDGET *wdgt;{ (void) wclear(wdgt->wndw); boxwdgt(wdgt, '-', '|'); if (wdgt->tvalues == (char **)NULL) return; mvwaddstr(wdgt->wndw,1,1,wdgt->label); (void) waddstr(wdgt->wndw,wdgt->tvalues[wdgt->tindx]); (void) wclrtoeol(wdgt->wndw); (void) mvwaddch(wdgt->wndw,1,wdgt->wdth-1,'|'); (void) wrefresh(wdgt->wndw);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?