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