xref: /dflybsd-src/usr.sbin/installer/dfuife_curses/curses_widget.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino  * Copyright (c)2004 Cat's Eye Technologies.  All rights reserved.
3*86d7f5d3SJohn Marino  *
4*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
5*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
6*86d7f5d3SJohn Marino  * are met:
7*86d7f5d3SJohn Marino  *
8*86d7f5d3SJohn Marino  *   Redistributions of source code must retain the above copyright
9*86d7f5d3SJohn Marino  *   notice, this list of conditions and the following disclaimer.
10*86d7f5d3SJohn Marino  *
11*86d7f5d3SJohn Marino  *   Redistributions in binary form must reproduce the above copyright
12*86d7f5d3SJohn Marino  *   notice, this list of conditions and the following disclaimer in
13*86d7f5d3SJohn Marino  *   the documentation and/or other materials provided with the
14*86d7f5d3SJohn Marino  *   distribution.
15*86d7f5d3SJohn Marino  *
16*86d7f5d3SJohn Marino  *   Neither the name of Cat's Eye Technologies nor the names of its
17*86d7f5d3SJohn Marino  *   contributors may be used to endorse or promote products derived
18*86d7f5d3SJohn Marino  *   from this software without specific prior written permission.
19*86d7f5d3SJohn Marino  *
20*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*86d7f5d3SJohn Marino  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*86d7f5d3SJohn Marino  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*86d7f5d3SJohn Marino  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*86d7f5d3SJohn Marino  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*86d7f5d3SJohn Marino  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26*86d7f5d3SJohn Marino  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27*86d7f5d3SJohn Marino  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*86d7f5d3SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29*86d7f5d3SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30*86d7f5d3SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31*86d7f5d3SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
32*86d7f5d3SJohn Marino  */
33*86d7f5d3SJohn Marino 
34*86d7f5d3SJohn Marino /*
35*86d7f5d3SJohn Marino  * curses_widget.c
36*86d7f5d3SJohn Marino  * $Id: curses_widget.c,v 1.12 2005/02/08 07:49:03 cpressey Exp $
37*86d7f5d3SJohn Marino  */
38*86d7f5d3SJohn Marino 
39*86d7f5d3SJohn Marino #include <ctype.h>
40*86d7f5d3SJohn Marino #include <ncurses.h>
41*86d7f5d3SJohn Marino #include <stdlib.h>
42*86d7f5d3SJohn Marino #include <string.h>
43*86d7f5d3SJohn Marino 
44*86d7f5d3SJohn Marino #include "libaura/mem.h"
45*86d7f5d3SJohn Marino 
46*86d7f5d3SJohn Marino #include "curses_form.h"
47*86d7f5d3SJohn Marino #include "curses_widget.h"
48*86d7f5d3SJohn Marino #include "curses_bar.h"
49*86d7f5d3SJohn Marino #include "curses_util.h"
50*86d7f5d3SJohn Marino 
51*86d7f5d3SJohn Marino #ifdef DEBUG
52*86d7f5d3SJohn Marino extern FILE *dfui_debug_file;
53*86d7f5d3SJohn Marino #endif
54*86d7f5d3SJohn Marino 
55*86d7f5d3SJohn Marino extern struct curses_bar *statusbar;
56*86d7f5d3SJohn Marino 
57*86d7f5d3SJohn Marino /*** WIDGETS ***/
58*86d7f5d3SJohn Marino 
59*86d7f5d3SJohn Marino /*
60*86d7f5d3SJohn Marino  * Create a new curses_widget, outside of the context of any particular
61*86d7f5d3SJohn Marino  * curses_form.
62*86d7f5d3SJohn Marino  */
63*86d7f5d3SJohn Marino struct curses_widget *
curses_widget_new(unsigned int x,unsigned int y,unsigned int width,widget_t type,const char * text,unsigned int size,unsigned int flags)64*86d7f5d3SJohn Marino curses_widget_new(unsigned int x, unsigned int y,
65*86d7f5d3SJohn Marino 		  unsigned int width, widget_t type,
66*86d7f5d3SJohn Marino 		  const char *text, unsigned int size,
67*86d7f5d3SJohn Marino 		  unsigned int flags)
68*86d7f5d3SJohn Marino {
69*86d7f5d3SJohn Marino 	struct curses_widget *w;
70*86d7f5d3SJohn Marino 
71*86d7f5d3SJohn Marino 	AURA_MALLOC(w, curses_widget);
72*86d7f5d3SJohn Marino 
73*86d7f5d3SJohn Marino 	w->form = NULL;
74*86d7f5d3SJohn Marino 
75*86d7f5d3SJohn Marino 	if (flags & CURSES_WIDGET_WIDEN) {
76*86d7f5d3SJohn Marino 		switch (type) {
77*86d7f5d3SJohn Marino 		case CURSES_TEXTBOX:
78*86d7f5d3SJohn Marino 			width = strlen(text) + 2;
79*86d7f5d3SJohn Marino 			break;
80*86d7f5d3SJohn Marino 		case CURSES_BUTTON:
81*86d7f5d3SJohn Marino 			width = strlen(text) + 4;
82*86d7f5d3SJohn Marino 			break;
83*86d7f5d3SJohn Marino 		default:
84*86d7f5d3SJohn Marino 			width = strlen(text);
85*86d7f5d3SJohn Marino 			break;
86*86d7f5d3SJohn Marino 		}
87*86d7f5d3SJohn Marino 	}
88*86d7f5d3SJohn Marino 
89*86d7f5d3SJohn Marino 	w->x = x;
90*86d7f5d3SJohn Marino 	w->y = y;
91*86d7f5d3SJohn Marino 	w->width = width;
92*86d7f5d3SJohn Marino 	w->type = type;
93*86d7f5d3SJohn Marino 	w->next = NULL;
94*86d7f5d3SJohn Marino 	w->prev = NULL;
95*86d7f5d3SJohn Marino 	w->flags = flags;
96*86d7f5d3SJohn Marino 	w->accel = '\0';
97*86d7f5d3SJohn Marino 
98*86d7f5d3SJohn Marino 	if (w->type == CURSES_TEXTBOX) {
99*86d7f5d3SJohn Marino 		w->size = size;
100*86d7f5d3SJohn Marino 		w->text = aura_malloc(size, "w->text");
101*86d7f5d3SJohn Marino 		strcpy(w->text, text);
102*86d7f5d3SJohn Marino 	} else {
103*86d7f5d3SJohn Marino 		w->text = aura_strdup(text);
104*86d7f5d3SJohn Marino 		w->size = strlen(text) + 1;
105*86d7f5d3SJohn Marino 		/* size argument is ignored */
106*86d7f5d3SJohn Marino 	}
107*86d7f5d3SJohn Marino 
108*86d7f5d3SJohn Marino 	w->curpos = strlen(w->text);
109*86d7f5d3SJohn Marino 	w->editable = 1;
110*86d7f5d3SJohn Marino 	w->obscured = 0;
111*86d7f5d3SJohn Marino 	w->offset = 0;
112*86d7f5d3SJohn Marino 	w->amount = 0;
113*86d7f5d3SJohn Marino 	w->spin = 0;
114*86d7f5d3SJohn Marino 	w->tooltip = NULL;
115*86d7f5d3SJohn Marino 	w->user_id = 0;
116*86d7f5d3SJohn Marino 	w->userdata = NULL;
117*86d7f5d3SJohn Marino 
118*86d7f5d3SJohn Marino 	w->click_cb = NULL;
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino 	return(w);
121*86d7f5d3SJohn Marino }
122*86d7f5d3SJohn Marino 
123*86d7f5d3SJohn Marino /*
124*86d7f5d3SJohn Marino  * Free the memory allocated for a curses_widget.  Note that this does
125*86d7f5d3SJohn Marino  * NOT free any allocated memory at the widget's userdata pointer.
126*86d7f5d3SJohn Marino  */
127*86d7f5d3SJohn Marino void
curses_widget_free(struct curses_widget * w)128*86d7f5d3SJohn Marino curses_widget_free(struct curses_widget *w)
129*86d7f5d3SJohn Marino {
130*86d7f5d3SJohn Marino 	if (w->tooltip != NULL)
131*86d7f5d3SJohn Marino 		free(w->tooltip);
132*86d7f5d3SJohn Marino 	free(w->text);
133*86d7f5d3SJohn Marino 	AURA_FREE(w, curses_widget);
134*86d7f5d3SJohn Marino }
135*86d7f5d3SJohn Marino 
136*86d7f5d3SJohn Marino void
curses_widget_tooltip_set(struct curses_widget * w,const char * tooltip)137*86d7f5d3SJohn Marino curses_widget_tooltip_set(struct curses_widget *w, const char *tooltip)
138*86d7f5d3SJohn Marino {
139*86d7f5d3SJohn Marino 	if (w->tooltip != NULL)
140*86d7f5d3SJohn Marino 		free(w->tooltip);
141*86d7f5d3SJohn Marino 	w->tooltip = aura_strdup(tooltip);
142*86d7f5d3SJohn Marino }
143*86d7f5d3SJohn Marino 
144*86d7f5d3SJohn Marino /*
145*86d7f5d3SJohn Marino  * Draw a curses_widget to the window of its associated curses_form.
146*86d7f5d3SJohn Marino  * Note that this does not refresh the screen.
147*86d7f5d3SJohn Marino  */
148*86d7f5d3SJohn Marino void
curses_widget_draw(struct curses_widget * w)149*86d7f5d3SJohn Marino curses_widget_draw(struct curses_widget *w)
150*86d7f5d3SJohn Marino {
151*86d7f5d3SJohn Marino 	unsigned int wx, wy, x, len, i, charpos, cutoff, fchpos;
152*86d7f5d3SJohn Marino 	char p[5];
153*86d7f5d3SJohn Marino 	char bar_char;
154*86d7f5d3SJohn Marino 	struct curses_form *cf = w->form;
155*86d7f5d3SJohn Marino 
156*86d7f5d3SJohn Marino 	wx = w->x + 1 - cf->x_offset;
157*86d7f5d3SJohn Marino 	wy = w->y + 1 - cf->y_offset;
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino 	/*
160*86d7f5d3SJohn Marino 	 * If the widget is outside the clipping rectangle of the
161*86d7f5d3SJohn Marino 	 * form, don't draw it.
162*86d7f5d3SJohn Marino 	 */
163*86d7f5d3SJohn Marino 	if (!curses_form_widget_is_visible(w))
164*86d7f5d3SJohn Marino 		return;
165*86d7f5d3SJohn Marino 
166*86d7f5d3SJohn Marino 	wmove(cf->win, wy, wx);
167*86d7f5d3SJohn Marino 
168*86d7f5d3SJohn Marino 	curses_colors_set(cf->win, w == cf->widget_focus ?
169*86d7f5d3SJohn Marino 	    CURSES_COLORS_FOCUS : CURSES_COLORS_CONTROL);
170*86d7f5d3SJohn Marino 
171*86d7f5d3SJohn Marino 	switch (w->type) {
172*86d7f5d3SJohn Marino 	case CURSES_LABEL:
173*86d7f5d3SJohn Marino 		curses_colors_set(cf->win, CURSES_COLORS_LABEL);	 /* XXX conditional on... */
174*86d7f5d3SJohn Marino 		waddnstr(cf->win, w->text, w->width);
175*86d7f5d3SJohn Marino 		curs_set(0);
176*86d7f5d3SJohn Marino 		break;
177*86d7f5d3SJohn Marino 	case CURSES_TEXTBOX:
178*86d7f5d3SJohn Marino 		waddstr(cf->win, "[");
179*86d7f5d3SJohn Marino 		curses_colors_set(cf->win, CURSES_COLORS_TEXT);		/* XXX focus ? */
180*86d7f5d3SJohn Marino 		charpos = w->offset;
181*86d7f5d3SJohn Marino 		len = strlen(w->text);
182*86d7f5d3SJohn Marino 		for (x = 0; x < w->width - 2; x++) {
183*86d7f5d3SJohn Marino 			if (charpos < len) {
184*86d7f5d3SJohn Marino 				waddch(cf->win, w->obscured ?
185*86d7f5d3SJohn Marino 				    '*' : w->text[charpos]);
186*86d7f5d3SJohn Marino 				charpos++;
187*86d7f5d3SJohn Marino 			} else {
188*86d7f5d3SJohn Marino 				waddch(cf->win, ' ');
189*86d7f5d3SJohn Marino 			}
190*86d7f5d3SJohn Marino 		}
191*86d7f5d3SJohn Marino 		curses_colors_set(cf->win, w == cf->widget_focus ?
192*86d7f5d3SJohn Marino 		    CURSES_COLORS_FOCUS : CURSES_COLORS_CONTROL);
193*86d7f5d3SJohn Marino 		waddstr(cf->win, "]");
194*86d7f5d3SJohn Marino 		/*
195*86d7f5d3SJohn Marino 		 * Position the cursor to where it's expected.
196*86d7f5d3SJohn Marino 		 */
197*86d7f5d3SJohn Marino 		if (w->curpos - w->offset < w->width - 2) {
198*86d7f5d3SJohn Marino 			wmove(cf->win, w->y + 1 - cf->y_offset,
199*86d7f5d3SJohn Marino 			      w->x + 2 - cf->x_offset + w->curpos - w->offset);
200*86d7f5d3SJohn Marino 		} else {
201*86d7f5d3SJohn Marino 			wmove(cf->win, w->y + 1 - cf->y_offset,
202*86d7f5d3SJohn Marino 			      w->x + 2 - cf->x_offset + w->width - 2);
203*86d7f5d3SJohn Marino 		}
204*86d7f5d3SJohn Marino 		curs_set(1);
205*86d7f5d3SJohn Marino 		break;
206*86d7f5d3SJohn Marino 	case CURSES_BUTTON:
207*86d7f5d3SJohn Marino 		waddstr(cf->win, "< ");
208*86d7f5d3SJohn Marino 		waddnstr(cf->win, w->text, w->width - 4);
209*86d7f5d3SJohn Marino 		waddstr(cf->win, " >");
210*86d7f5d3SJohn Marino 		if (isprint(w->accel)) {
211*86d7f5d3SJohn Marino 			for (i = 0; w->text[i] != '\0'; i++) {
212*86d7f5d3SJohn Marino 				if (toupper(w->text[i]) == w->accel) {
213*86d7f5d3SJohn Marino 					wmove(cf->win, wy, wx + 2 + i);
214*86d7f5d3SJohn Marino 					curses_colors_set(cf->win, w == cf->widget_focus ?
215*86d7f5d3SJohn Marino 					    CURSES_COLORS_ACCELFOCUS : CURSES_COLORS_ACCEL);
216*86d7f5d3SJohn Marino 					waddch(cf->win, w->text[i]);
217*86d7f5d3SJohn Marino 					break;
218*86d7f5d3SJohn Marino 				}
219*86d7f5d3SJohn Marino 			}
220*86d7f5d3SJohn Marino 		}
221*86d7f5d3SJohn Marino 		curs_set(0);
222*86d7f5d3SJohn Marino 		break;
223*86d7f5d3SJohn Marino 	case CURSES_PROGRESS:
224*86d7f5d3SJohn Marino 		waddstr(cf->win, "[");
225*86d7f5d3SJohn Marino 		snprintf(p, 5, "%3d%%", w->amount);
226*86d7f5d3SJohn Marino 		cutoff = (w->amount * (w->width - 2)) / 100;
227*86d7f5d3SJohn Marino 		fchpos = ((w->width - 2) / 2) - 2;
228*86d7f5d3SJohn Marino 		for (x = 0; x < w->width - 2; x++) {
229*86d7f5d3SJohn Marino 			if (x < cutoff) {
230*86d7f5d3SJohn Marino 				curses_colors_set(cf->win, CURSES_COLORS_FOCUS);/* XXX status ? */
231*86d7f5d3SJohn Marino 				bar_char = monochrome ? '=' : ' ';
232*86d7f5d3SJohn Marino 			} else {
233*86d7f5d3SJohn Marino 				curses_colors_set(cf->win, CURSES_COLORS_CONTROL);
234*86d7f5d3SJohn Marino 				bar_char = ' ';
235*86d7f5d3SJohn Marino 			}
236*86d7f5d3SJohn Marino 
237*86d7f5d3SJohn Marino 			if (x >= fchpos && x <= fchpos + 3)
238*86d7f5d3SJohn Marino 				waddch(cf->win, p[x - fchpos]);
239*86d7f5d3SJohn Marino 			else
240*86d7f5d3SJohn Marino 				waddch(cf->win, bar_char);
241*86d7f5d3SJohn Marino 		}
242*86d7f5d3SJohn Marino 		waddstr(cf->win, "]");
243*86d7f5d3SJohn Marino 		curs_set(0);
244*86d7f5d3SJohn Marino 		break;
245*86d7f5d3SJohn Marino 	case CURSES_CHECKBOX:
246*86d7f5d3SJohn Marino 		waddstr(cf->win, "[");
247*86d7f5d3SJohn Marino 		waddstr(cf->win, w->amount ? "X" : " ");
248*86d7f5d3SJohn Marino 		waddstr(cf->win, "]");
249*86d7f5d3SJohn Marino 		curs_set(0);
250*86d7f5d3SJohn Marino 		break;
251*86d7f5d3SJohn Marino 	}
252*86d7f5d3SJohn Marino }
253*86d7f5d3SJohn Marino 
254*86d7f5d3SJohn Marino void
curses_widget_draw_tooltip(struct curses_widget * w)255*86d7f5d3SJohn Marino curses_widget_draw_tooltip(struct curses_widget *w)
256*86d7f5d3SJohn Marino {
257*86d7f5d3SJohn Marino 	if (w->tooltip != NULL)
258*86d7f5d3SJohn Marino 		curses_bar_set_text(statusbar, w->tooltip);
259*86d7f5d3SJohn Marino }
260*86d7f5d3SJohn Marino 
261*86d7f5d3SJohn Marino /*
262*86d7f5d3SJohn Marino  * Returns non-zero if the given widget can take control focus
263*86d7f5d3SJohn Marino  * (i.e. if it is not a label, progress bar, or other inert element.)
264*86d7f5d3SJohn Marino  */
265*86d7f5d3SJohn Marino int
curses_widget_can_take_focus(struct curses_widget * w)266*86d7f5d3SJohn Marino curses_widget_can_take_focus(struct curses_widget *w)
267*86d7f5d3SJohn Marino {
268*86d7f5d3SJohn Marino 	if (w->type == CURSES_LABEL || w->type == CURSES_PROGRESS)
269*86d7f5d3SJohn Marino 		return(0);
270*86d7f5d3SJohn Marino 	return(1);
271*86d7f5d3SJohn Marino }
272*86d7f5d3SJohn Marino 
273*86d7f5d3SJohn Marino int
curses_widget_set_click_cb(struct curses_widget * w,int (* callback)(struct curses_widget *))274*86d7f5d3SJohn Marino curses_widget_set_click_cb(struct curses_widget *w,
275*86d7f5d3SJohn Marino 			   int (*callback)(struct curses_widget *))
276*86d7f5d3SJohn Marino {
277*86d7f5d3SJohn Marino 	w->click_cb = callback;
278*86d7f5d3SJohn Marino 	return(1);
279*86d7f5d3SJohn Marino }
280*86d7f5d3SJohn Marino 
281*86d7f5d3SJohn Marino /*
282*86d7f5d3SJohn Marino  * Returns:
283*86d7f5d3SJohn Marino  *   -1 to indicate that the widget is not clickable.
284*86d7f5d3SJohn Marino  *    0 to indicate that the widget clicked.
285*86d7f5d3SJohn Marino  *    1 to indicate that the widget clicked and that its form should close.
286*86d7f5d3SJohn Marino  */
287*86d7f5d3SJohn Marino int
curses_widget_click(struct curses_widget * w)288*86d7f5d3SJohn Marino curses_widget_click(struct curses_widget *w)
289*86d7f5d3SJohn Marino {
290*86d7f5d3SJohn Marino 	if ((w->type != CURSES_BUTTON && w->type != CURSES_TEXTBOX) ||
291*86d7f5d3SJohn Marino 	    w->click_cb == NULL)
292*86d7f5d3SJohn Marino 		return(-1);
293*86d7f5d3SJohn Marino 
294*86d7f5d3SJohn Marino 	return(w->click_cb(w));
295*86d7f5d3SJohn Marino }
296*86d7f5d3SJohn Marino 
297*86d7f5d3SJohn Marino /*** TEXTBOX WIDGETS ***/
298*86d7f5d3SJohn Marino 
299*86d7f5d3SJohn Marino int
curses_textbox_advance_char(struct curses_widget * w)300*86d7f5d3SJohn Marino curses_textbox_advance_char(struct curses_widget *w)
301*86d7f5d3SJohn Marino {
302*86d7f5d3SJohn Marino 	if (w->text[w->curpos] != '\0') {
303*86d7f5d3SJohn Marino 		w->curpos++;
304*86d7f5d3SJohn Marino 		if ((w->curpos - w->offset) >= (w->width - 2))
305*86d7f5d3SJohn Marino 			w->offset++;
306*86d7f5d3SJohn Marino 		curses_widget_draw(w);
307*86d7f5d3SJohn Marino 		curses_form_refresh(w->form);
308*86d7f5d3SJohn Marino 		return(1);
309*86d7f5d3SJohn Marino 	} else {
310*86d7f5d3SJohn Marino 		return(0);
311*86d7f5d3SJohn Marino 	}
312*86d7f5d3SJohn Marino }
313*86d7f5d3SJohn Marino 
314*86d7f5d3SJohn Marino int
curses_textbox_retreat_char(struct curses_widget * w)315*86d7f5d3SJohn Marino curses_textbox_retreat_char(struct curses_widget *w)
316*86d7f5d3SJohn Marino {
317*86d7f5d3SJohn Marino 	if (w->curpos > 0) {
318*86d7f5d3SJohn Marino 		w->curpos--;
319*86d7f5d3SJohn Marino 		if (w->curpos < w->offset)
320*86d7f5d3SJohn Marino 			w->offset--;
321*86d7f5d3SJohn Marino 		curses_widget_draw(w);
322*86d7f5d3SJohn Marino 		curses_form_refresh(w->form);
323*86d7f5d3SJohn Marino 		return(1);
324*86d7f5d3SJohn Marino 	} else {
325*86d7f5d3SJohn Marino 		return(0);
326*86d7f5d3SJohn Marino 	}
327*86d7f5d3SJohn Marino }
328*86d7f5d3SJohn Marino 
329*86d7f5d3SJohn Marino int
curses_textbox_home(struct curses_widget * w)330*86d7f5d3SJohn Marino curses_textbox_home(struct curses_widget *w)
331*86d7f5d3SJohn Marino {
332*86d7f5d3SJohn Marino 	w->curpos = 0;
333*86d7f5d3SJohn Marino 	w->offset = 0;
334*86d7f5d3SJohn Marino 	curses_widget_draw(w);
335*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
336*86d7f5d3SJohn Marino 	return(1);
337*86d7f5d3SJohn Marino }
338*86d7f5d3SJohn Marino 
339*86d7f5d3SJohn Marino int
curses_textbox_end(struct curses_widget * w)340*86d7f5d3SJohn Marino curses_textbox_end(struct curses_widget *w)
341*86d7f5d3SJohn Marino {
342*86d7f5d3SJohn Marino 	w->curpos = strlen(w->text);
343*86d7f5d3SJohn Marino 	while ((w->curpos - w->offset) >= (w->width - 2)) {
344*86d7f5d3SJohn Marino 		w->offset++;
345*86d7f5d3SJohn Marino 	}
346*86d7f5d3SJohn Marino 	curses_widget_draw(w);
347*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
348*86d7f5d3SJohn Marino 	return(1);
349*86d7f5d3SJohn Marino }
350*86d7f5d3SJohn Marino 
351*86d7f5d3SJohn Marino int
curses_textbox_insert_char(struct curses_widget * w,char key)352*86d7f5d3SJohn Marino curses_textbox_insert_char(struct curses_widget *w, char key)
353*86d7f5d3SJohn Marino {
354*86d7f5d3SJohn Marino 	unsigned int len, i;
355*86d7f5d3SJohn Marino 
356*86d7f5d3SJohn Marino 	if (!w->editable)
357*86d7f5d3SJohn Marino 		return(0);
358*86d7f5d3SJohn Marino 
359*86d7f5d3SJohn Marino 	len = strlen(w->text);
360*86d7f5d3SJohn Marino 	if (len == (w->size - 1))
361*86d7f5d3SJohn Marino 		return(0);
362*86d7f5d3SJohn Marino 
363*86d7f5d3SJohn Marino 	w->text[len + 1] = '\0';
364*86d7f5d3SJohn Marino 	for (i = len; i > w->curpos; i--)
365*86d7f5d3SJohn Marino 		w->text[i] = w->text[i - 1];
366*86d7f5d3SJohn Marino 	w->text[w->curpos++] = key;
367*86d7f5d3SJohn Marino 	if ((w->curpos - w->offset) >= (w->width - 2))
368*86d7f5d3SJohn Marino 		w->offset++;
369*86d7f5d3SJohn Marino 	curses_widget_draw(w);
370*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
371*86d7f5d3SJohn Marino 	return(1);
372*86d7f5d3SJohn Marino }
373*86d7f5d3SJohn Marino 
374*86d7f5d3SJohn Marino int
curses_textbox_backspace_char(struct curses_widget * w)375*86d7f5d3SJohn Marino curses_textbox_backspace_char(struct curses_widget *w)
376*86d7f5d3SJohn Marino {
377*86d7f5d3SJohn Marino 	int len, i;
378*86d7f5d3SJohn Marino 
379*86d7f5d3SJohn Marino 	if (!w->editable)
380*86d7f5d3SJohn Marino 		return(0);
381*86d7f5d3SJohn Marino 
382*86d7f5d3SJohn Marino 	len = strlen(w->text);
383*86d7f5d3SJohn Marino 	if (w->curpos == 0)
384*86d7f5d3SJohn Marino 		return(0);
385*86d7f5d3SJohn Marino 
386*86d7f5d3SJohn Marino 	for (i = w->curpos; i <= len; i++)
387*86d7f5d3SJohn Marino 		w->text[i - 1] = w->text[i];
388*86d7f5d3SJohn Marino 	w->curpos--;
389*86d7f5d3SJohn Marino 	if (w->curpos < w->offset)
390*86d7f5d3SJohn Marino 		w->offset--;
391*86d7f5d3SJohn Marino 	curses_widget_draw(w);
392*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
393*86d7f5d3SJohn Marino 	return(1);
394*86d7f5d3SJohn Marino }
395*86d7f5d3SJohn Marino 
396*86d7f5d3SJohn Marino int
curses_textbox_delete_char(struct curses_widget * w)397*86d7f5d3SJohn Marino curses_textbox_delete_char(struct curses_widget *w)
398*86d7f5d3SJohn Marino {
399*86d7f5d3SJohn Marino 	unsigned int len, i;
400*86d7f5d3SJohn Marino 
401*86d7f5d3SJohn Marino 	if (!w->editable)
402*86d7f5d3SJohn Marino 		return(0);
403*86d7f5d3SJohn Marino 
404*86d7f5d3SJohn Marino 	len = strlen(w->text);
405*86d7f5d3SJohn Marino 	if (w->curpos == len)
406*86d7f5d3SJohn Marino 		return(0);
407*86d7f5d3SJohn Marino 
408*86d7f5d3SJohn Marino 	for (i = w->curpos + 1; i <= len; i++)
409*86d7f5d3SJohn Marino 		w->text[i - 1] = w->text[i];
410*86d7f5d3SJohn Marino 	curses_widget_draw(w);
411*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
412*86d7f5d3SJohn Marino 	return(1);
413*86d7f5d3SJohn Marino }
414*86d7f5d3SJohn Marino 
415*86d7f5d3SJohn Marino int
curses_textbox_set_text(struct curses_widget * w,const char * text)416*86d7f5d3SJohn Marino curses_textbox_set_text(struct curses_widget *w, const char *text)
417*86d7f5d3SJohn Marino {
418*86d7f5d3SJohn Marino 	strlcpy(w->text, text, w->size);
419*86d7f5d3SJohn Marino 	w->curpos = strlen(w->text);
420*86d7f5d3SJohn Marino 	curses_widget_draw(w);
421*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
422*86d7f5d3SJohn Marino 	return(1);
423*86d7f5d3SJohn Marino }
424*86d7f5d3SJohn Marino 
425*86d7f5d3SJohn Marino /*** CHECKBOX WIDGETS ***/
426*86d7f5d3SJohn Marino 
427*86d7f5d3SJohn Marino int
curses_checkbox_toggle(struct curses_widget * w)428*86d7f5d3SJohn Marino curses_checkbox_toggle(struct curses_widget *w)
429*86d7f5d3SJohn Marino {
430*86d7f5d3SJohn Marino 	if (!w->editable)
431*86d7f5d3SJohn Marino 		return(0);
432*86d7f5d3SJohn Marino 	w->amount = !w->amount;
433*86d7f5d3SJohn Marino 	curses_widget_draw(w);
434*86d7f5d3SJohn Marino 	curses_form_refresh(w->form);
435*86d7f5d3SJohn Marino 	return(1);
436*86d7f5d3SJohn Marino }
437*86d7f5d3SJohn Marino 
438*86d7f5d3SJohn Marino /*** PROGRESS WIDGETS ***/
439*86d7f5d3SJohn Marino 
440*86d7f5d3SJohn Marino char spinny[5] = "/-\\|";
441*86d7f5d3SJohn Marino 
442*86d7f5d3SJohn Marino int
curses_progress_spin(struct curses_widget * w)443*86d7f5d3SJohn Marino curses_progress_spin(struct curses_widget *w)
444*86d7f5d3SJohn Marino {
445*86d7f5d3SJohn Marino 	struct curses_form *cf = w->form;
446*86d7f5d3SJohn Marino 	int wx, wy;
447*86d7f5d3SJohn Marino 
448*86d7f5d3SJohn Marino 	if (w->type != CURSES_PROGRESS)
449*86d7f5d3SJohn Marino 		return(0);
450*86d7f5d3SJohn Marino 
451*86d7f5d3SJohn Marino 	wx = w->x + 1 - cf->x_offset;
452*86d7f5d3SJohn Marino 	wy = w->y + 1 - cf->y_offset;
453*86d7f5d3SJohn Marino 
454*86d7f5d3SJohn Marino 	w->spin = (w->spin + 1) % 4;
455*86d7f5d3SJohn Marino 	curses_colors_set(cf->win, CURSES_COLORS_FOCUS);/* XXX status ? */
456*86d7f5d3SJohn Marino 	mvwaddch(cf->win, wy, wx + 1, spinny[w->spin]);
457*86d7f5d3SJohn Marino 
458*86d7f5d3SJohn Marino 	return(1);
459*86d7f5d3SJohn Marino }
460