1 /**
2 *	iloop.c	--	nsf subroutine
3 **/
4 #include	<stdio.h>
5 #include	<ctype.h>
6 #include	"nsf.h"
7 
8 /**
9 *	mesg() -- message to user.
10 **/
mesg(s)11 void mesg(s)
12 char	*s;
13 {
14 	int	i;
15 	if (s != NULL) beep();
16 	if (s == NULL)
17 	s="Next Field: TAB     1st Field: HOME    Help: ESC     End: RETURN";
18 	move(LINES-1,0);
19 	clrtoeol();
20 	i = (COLS - strlen(s))/2;
21 	move(LINES-1,i);
22 	if (use_uline) attroff(A_UNDERLINE);
23 	addstr(s);
24 	if (use_uline) attron(A_UNDERLINE);
25 	move(fld[cfld].y,fld[cfld].x+ccol);
26 }
27 /**
28 *	backspace()
29 **/
backspace()30 void backspace(){
31 	struct	INFLD *p;
32 	int	y,x,c,i;
33 	p = &fld[cfld];
34 	y = p->y;
35 	x = p->x+ccol;
36 	if (ccol < 1){
37 		cfld--;
38 		if (cfld < 0) cfld = nfld - 1;
39 		ccol = 0;
40 		return;
41 	}
42 	if (ccol == (p->len - 1)){
43 		c = mvinch(y,x);
44 		if ((c & 0xff) != ' '){
45 			addch(' ');
46 			return;
47 		}
48 	}
49 	for(i = ccol ; i < fld[cfld].len ; ++i){
50 		x = fld[cfld].x + i;
51 		c = mvinch(y,x);
52 		mvaddch(y,x-1,c);
53 	}
54 	mvaddch(y,fld[cfld].x+fld[cfld].len-1,' ');
55 	ccol--;
56 }
57 /**
58 *	field_get()	get field value if it's ok.
59 **/
field_get()60 int field_get(){
61 	struct INFLD *p;
62 	int	i;
63 	char	buf[BUFSIZ],*s;
64 	p = &fld[cfld];
65 	for(i = 0 ; i < p->len ; i++){
66 		move (p->y,p->x + i);
67 		buf[i] = (char)inch();
68 	}
69 	for(i = p->len - 1; i >= 0 ; i--) if (buf[i] != ' ') break;
70 	buf[++i] = '\0';
71 	if (!(p->attr & SF_SELECT) && p->attr & (SF_DIGITS|SF_REAL)){
72 		s = &buf[0];
73 		while (*s == ' ') ++s;
74 		if (*s == '+' || *s == '-') ++s;
75 		while(*s >= '0' && *s <= '9') ++s;
76 		if (p->attr & SF_REAL){
77 			if (*s == '.') ++s;
78 			while (*s >= '0' && *s <= '9') ++s;
79 		}
80 		if (*s != '\0'){
81 			if (p->attr & SF_REAL) mesg("MUST BE NUMERIC");
82 			else mesg("MUST BE INTEGER NUMBER.");
83 			return 0;
84 		}
85 	}
86 	strcpy(p->inp,buf);
87 	return 1;
88 }
89 /**
90 *	end_ok()
91 **/
end_ok()92 int end_ok(){
93 	ccol = 0;
94 	for(cfld = 0 ; cfld < nfld ; ++cfld){
95 		if (!field_get()) return 0;
96 		if ((fld[cfld].attr & SF_FORCE) && fld[cfld].inp[0] == '\0'){
97 			mesg("YOU CAN NOT OMIT THIS ITEM.");
98 			return 0;
99 		}
100 	}
101 	return 1;
102 }
103 /**
104 *	field_move()	move cfld and ccol
105 **/
field_move(c)106 void field_move(c)
107 int	c;
108 {
109 	int i,x,y,yy;
110 
111 	if (c == KEY_HOME){
112 		cfld = ccol = 0;
113 		move(fld[0].y,fld[0].x);
114 		return;
115 	}
116 	x = fld[cfld].x + ccol;
117 	y = fld[cfld].y;
118 	if (c == KEY_DOWN || c == '\012'){
119 		for(i = (cfld + 1) % nfld;;i = (i+1)%nfld)
120 			if ((yy = fld[i].y) != y) break;
121 		for(i++;i < nfld && fld[i].y == yy;i++)
122 			if (fld[i].x > x) break;
123 		i--;
124 	}else if (c == KEY_UP){
125 		for(i = (cfld + nfld - 1) % nfld;;i = (i+nfld-1)%nfld)
126 			if ((yy = fld[i].y) != y) break;
127 		for(i--;i >= 0 && fld[i].y == yy;i--)
128 			if (fld[i].x+fld[i].len < x) break;
129 		i++;
130 	}else if (c == '\t'){
131 		i = cfld + 1;
132 		if (i >= nfld) i = 0;
133 	}else if (c == '\r'){
134 		for(i = cfld ; i < nfld ; ++i) if (fld[i].y > y) break;
135 	}
136 	if (i >= nfld || i < 0){
137 		beep();
138 		move(fld[cfld].y,fld[cfld].x+ccol);
139 		return;
140 	}
141 	cfld = i;
142 	ccol = 0;
143 	move(fld[cfld].y,fld[cfld].x+ccol);
144 }
145 /**
146 *	next_option()	display next option.
147 **/
next_option()148 void next_option(){
149 	struct INFLD *p;
150 	int	i;
151 	field_get();
152 	p = &fld[cfld];
153 	for(i = 0 ; i < p->len ; ++i) move(p->y,p->x+i),addch(' ');
154 	for(i = 0 ; i < p->nopt ; ++i) if (!strcmp(p->inp,p->opt[i])) break;
155 	if (++i >= p->nopt) i = 0;
156 	move(p->y,p->x);
157 	addstr(p->opt[i]);
158 	move(p->y,p->x);
159 }
iloop()160 void iloop(){
161 	int	i,c;
162 	char	buf[80];
163 	struct INFLD *p;
164 	if (cfld < 0) cfld = 0;
165 	if (cfld > nfld) cfld = nfld - 1;
166 	ccol = 0;
167 	if (use_uline) attron(A_UNDERLINE);
168 	for(i = 0 ; i < nfld ; ++i){
169 		p = &fld[i];
170 		move(p->y,p->x);
171 		addstr(p->def);
172 	}
173 	move(fld[cfld].y,fld[cfld].x);
174 	leaveok(stdscr,FALSE);
175 	if (initmesg[0] != '\0') mesg(initmesg);
176 	else mesg(NULL);
177 	while (1){
178 		move(fld[cfld].y,fld[cfld].x+ccol);
179 		refresh();
180 		c = getch();
181 		c &= 0x1ff;
182 		mesg(NULL);
183 		if (c == '\r'){
184 			if (!field_get()) continue;
185 			if (end_ok()) break;
186 		}else if (c == KEY_DOWN || c == KEY_UP ||
187 			c == KEY_HOME || c == '\t'|| c == '\012'){
188 			if (!field_get()) continue;
189 			field_move(c);
190 		}else if (c == KEY_LEFT){
191 			if (ccol > 0) ccol--;
192 			else{
193 				cfld--;
194 				if (cfld < 0) cfld = nfld - 1;
195 				ccol = fld[cfld].len - 1;
196 			}
197 		}else if (c == KEY_RIGHT){
198 			if (ccol < (fld[cfld].len - 1)) ccol++;
199 			else{
200 				cfld++;
201 				if (cfld >= nfld) cfld = 0;
202 				ccol = 0;
203 			}
204 		}else if (c == '\033'){	/* ESC */
205 			if (fld[cfld].help[0] == '\0') mesg(NULL);
206 			else	mesg(fld[cfld].help);
207 		}else if (fld[cfld].attr & SF_SELECT){
208 			if (c != ' ') mesg("HIT SPACE KEY TO CHANGE");
209 			else next_option();
210 		}else if (c == KEY_BACKSPACE || c == '\010'){
211 			backspace();
212 		}else if (c >= ' ' && c <= '}'){
213 			if (fld[cfld].attr & SF_UCASE) c = toupper(c);
214 			else if (fld[cfld].attr & SF_LCASE) c = tolower(c);
215 			addch(c);
216 			if ((ccol+1) >= fld[cfld].len){
217 				if (!field_get()) continue;
218 				if (fld[cfld].attr & SF_ASCEND)
219 					field_move('\t');
220 			}else{
221 				ccol++;
222 			}
223 		}else if (c == '\014'){
224 			clearok(stdscr,TRUE);
225 		}else{
226 			beep();
227 			if (debug_on){
228 				sprintf(buf,"0x%x (\\%o) comes",c,c);
229 				mesg(buf);
230 			}
231 		}
232 	}
233 }
234