diff options
author | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-12-06 10:35:28 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-12-06 10:35:28 +0000 |
commit | 1b308d0631e5d0d21b631a688cdef1afe378e086 (patch) | |
tree | 29376e960cd070b8a1642a30963497d9e673423d /lib | |
parent | 857c66bb5f3c5651b012beb1b5ea6ba39354ea94 (diff) | |
download | src-1b308d0631e5d0d21b631a688cdef1afe378e086.tar.gz src-1b308d0631e5d0d21b631a688cdef1afe378e086.zip |
bsddialog: vendor import 2021-12-05
Diffstat (limited to 'lib')
-rw-r--r-- | lib/GNUMakefile | 7 | ||||
-rw-r--r-- | lib/Makefile | 7 | ||||
-rw-r--r-- | lib/barbox.c | 498 | ||||
-rw-r--r-- | lib/bsddialog.3 | 42 | ||||
-rw-r--r-- | lib/bsddialog.h | 181 | ||||
-rw-r--r-- | lib/bsddialog_theme.h | 87 | ||||
-rw-r--r-- | lib/commandbox.c | 211 | ||||
-rw-r--r-- | lib/editorbox.c | 45 | ||||
-rw-r--r-- | lib/filebox.c | 52 | ||||
-rw-r--r-- | lib/formbox.c | 554 | ||||
-rw-r--r-- | lib/infobox.c | 10 | ||||
-rw-r--r-- | lib/lib_util.c | 448 | ||||
-rw-r--r-- | lib/lib_util.h | 46 | ||||
-rw-r--r-- | lib/libbsddialog.c | 13 | ||||
-rw-r--r-- | lib/menubox.c | 221 | ||||
-rw-r--r-- | lib/messagebox.c | 26 | ||||
-rw-r--r-- | lib/textbox.c | 67 | ||||
-rw-r--r-- | lib/theme.c | 354 | ||||
-rw-r--r-- | lib/timebox.c | 458 |
19 files changed, 1743 insertions, 1584 deletions
diff --git a/lib/GNUMakefile b/lib/GNUMakefile index 26dbdce9d4a0..045b58828a07 100644 --- a/lib/GNUMakefile +++ b/lib/GNUMakefile @@ -1,15 +1,14 @@ # PUBLIC DOMAIN - NO WARRANTY, see: # <http://creativecommons.org/publicdomain/zero/1.0/> # -# Written by Alfonso Sabato Siciliano +# Written in 2021 by Alfonso Sabato Siciliano VERSION = 0.1 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} HEADERS = bsddialog.h bsddialog_theme.h -SOURCES = barbox.c editorbox.c formbox.c lib_util.c menubox.c textbox.c \ - timebox.c commandbox.c filebox.c infobox.c libbsddialog.c messagebox.c \ - theme.c +SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ + messagebox.c textbox.c theme.c timebox.c OBJECTS = $(SOURCES:.c=.o) CFLAGS = -g -Wall -Werror -fpic LDFLAGS = -lform -lncurses -ltinfo diff --git a/lib/Makefile b/lib/Makefile index 74b6bc174a38..99dfea4d77e0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,15 +1,14 @@ # Any copyright is dedicated to the Public Domain, see: # <http://creativecommons.org/publicdomain/zero/1.0/> # -# Written by Alfonso Sabato Siciliano +# Written in 2021 by Alfonso Sabato Siciliano VERSION = 0.1 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} HEADERS = bsddialog.h bsddialog_theme.h -SOURCES = barbox.c editorbox.c formbox.c lib_util.c menubox.c textbox.c \ - timebox.c commandbox.c filebox.c infobox.c libbsddialog.c messagebox.c \ - theme.c +SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ + messagebox.c textbox.c theme.c timebox.c OBJECTS= ${SOURCES:.c=.o} FBSDFLAGS= -O2 -pipe -std=gnu99 -Wno-format-zero-length \ -fstack-protector-strong -Qunused-arguments diff --git a/lib/barbox.c b/lib/barbox.c index bb341605d6f5..b0d5c0febcf8 100644 --- a/lib/barbox.c +++ b/lib/barbox.c @@ -25,6 +25,9 @@ * SUCH DAMAGE. */ +#include <sys/param.h> + +#include <ctype.h> #include <stdlib.h> #include <string.h> @@ -38,12 +41,18 @@ #include "lib_util.h" #include "bsddialog_theme.h" +#define BARMARGIN 3 +#define MINBARWIDTH 10 +#define MINWIDTH (VBORDERS + MINBARWIDTH + BARMARGIN * 2) +#define MINHEIGHT 7 /* without text */ + /* "Bar": gauge - mixedgauge - rangebox - pause */ extern struct bsddialog_theme t; static void -draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel, int label) +draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel, + int label) { char labelstr[128]; int i, blue_x, color; @@ -52,7 +61,7 @@ draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel, int wmove(win, y, x); for (i = 0; i < size; i++) { - color = (i <= blue_x) ? t.currbarcolor : t.barcolor; + color = (i <= blue_x) ? t.bar.f_color : t.bar.color; wattron(win, color); waddch(win, ' '); wattroff(win, color); @@ -64,34 +73,106 @@ draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel, int sprintf(labelstr, "%3d%%", perc); wmove(win, y, x + size/2 - 2); for (i=0; i < (int) strlen(labelstr); i++) { - color = ( (blue_x + 1) <= (size/2 - (int) strlen(labelstr)/2 + i) ) ? - t.barcolor : t.currbarcolor; + color = (blue_x + 1 <= size/2 - (int)strlen(labelstr)/2 + i ) ? + t.bar.color : t.bar.f_color; wattron(win, color); waddch(win, labelstr[i]); wattroff(win, color); } } -int bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols, int perc) +static int +bar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, + char *text, struct buttons *bs) { - WINDOW *widget, *bar, *shadow; - char input[2048]; - int i, y, x; - bool mainloop = true; + int maxword, maxline, nlines, buttonswidth; - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - false) <0) - return -1; + if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0) + return BSDDIALOG_ERROR; - bar = new_boxed_window(conf, y+rows -4, x+3, 3, cols-6, RAISED); + buttonswidth = 0; + if (bs != NULL) { /* gauge has not buttons */ + buttonswidth= bs->nbuttons * bs->sizebutton; + if (bs->nbuttons > 0) + buttonswidth += (bs->nbuttons-1) * t.button.space; + } - wrefresh(widget); - wrefresh(bar); + if (cols == BSDDIALOG_AUTOSIZE) { + *w = VBORDERS; + /* buttons size */ + *w += buttonswidth; + /* bar size */ + *w = MAX(*w, MINWIDTH); + /* text size*/ + *w = MAX((int)(maxline + VBORDERS + t.text.hmargin * 2), *w); + /* avoid terminal overflow */ + *w = MIN(*w, widget_max_width(conf)); + } - while (mainloop) { - draw_perc_bar(bar, 1, 1, cols-8, perc, false, -1 /*unused*/); + if (rows == BSDDIALOG_AUTOSIZE) { + *h = MINHEIGHT; + if (maxword > 0) + *h += 1; + /* avoid terminal overflow */ + *h = MIN(*h, widget_max_height(conf)); + } + + return (0); +} +static int +bar_checksize(char *text, int rows, int cols, struct buttons *bs) +{ + int minheight, minwidth; + + minwidth = 0; + if (bs != NULL) { /* gauge has not buttons */ + minwidth = bs->nbuttons * bs->sizebutton; + if (bs->nbuttons > 0) + minwidth += (bs->nbuttons-1) * t.button.space; + } + minwidth = MAX(minwidth + VBORDERS, MINBARWIDTH); + + if (cols< minwidth) + RETURN_ERROR("Few cols for this widget"); + + minheight = MINHEIGHT + ((text != NULL && strlen(text) > 0) ? 1 : 0); + if (rows < minheight) + RETURN_ERROR("Few rows for this mixedgauge"); + + return 0; +} + +int +bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int perc) +{ + WINDOW *widget, *textpad, *bar, *shadow; + char input[2048], ntext[2048], *pntext; + int y, x, h, w, htextpad; + bool mainloop; + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (bar_autosize(conf, rows, cols, &h, &w, text, NULL) != 0) + return BSDDIALOG_ERROR; + if (bar_checksize(text, h, w, NULL) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, false) != 0) + return BSDDIALOG_ERROR; + + bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED); + + mainloop = true; + while (mainloop) { wrefresh(widget); + prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-4, + x+w-1-t.text.hmargin); + draw_perc_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/); wrefresh(bar); while (true) { @@ -106,9 +187,10 @@ int bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols, scanf("%d", &perc); perc = perc < 0 ? 0 : perc; perc = perc > 100 ? 100 : perc; - i = 2; - wmove(widget, 1, 1); - wclrtoeol(widget); + htextpad = 1; + wclear(textpad); + pntext = &ntext[0]; + ntext[0] = '\0'; while (true) { scanf("%s", input); if (strcmp(input,"EOF") == 0) { @@ -117,24 +199,28 @@ int bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols, } if (strcmp(input,"XXX") == 0) break; - //print_text(conf, widget, 1, 1, cols-2, input); - mvwaddstr(widget, 1, i, input); - i = i + strlen(input) + 1; - wrefresh(widget); + pntext[0] = ' '; + pntext++; + strcpy(pntext, input); + pntext += strlen(input); } + print_textpad(conf, textpad, &htextpad, w-2-t.text.hmargin*2, + ntext); } delwin(bar); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return BSDDIALOG_YESOK; } -int bsddialog_mixedgauge(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int perc, int argc, char **argv) +int +bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int mainperc, unsigned int nminbars, char **minibars) { - WINDOW *widget, *bar, *shadow; - int i, miniperc, y, x; + WINDOW *widget, *textpad, *bar, *shadow; + int i, output, miniperc, y, x, h, w, max_minbarlen; + int maxword, maxline, nlines, htextpad, ypad; char states[11][16] = { "[ Succeeded ]", "[ Failed ]", @@ -146,97 +232,156 @@ int bsddialog_mixedgauge(struct bsddialog_conf conf, char* text, int rows, int c "[ In Progress ]", "!!! BLANK !!!", "[ N/A ]", - "[ UNKNOWN ]",}; + "[ UNKNOWN ]", + }; + + if (nminbars % 2 !=0) + RETURN_ERROR("Mixedgauge wants a pair name/perc"); - if (new_widget(conf, &widget, &y, &x, NULL, &rows, &cols, &shadow, - false) <0) - return -1; + max_minbarlen = 0; + for (i=0; i < (int)(nminbars/2); i++) + max_minbarlen = MAX(max_minbarlen, (int) strlen(minibars[i*2])); + max_minbarlen += 3 + 16 /* seps + [...] or mainbar */; + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + + /* mixedgauge autosize */ + if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0) + return BSDDIALOG_ERROR; + + if (cols == BSDDIALOG_AUTOSIZE) { + w = max_minbarlen + HBORDERS; + w = MAX(max_minbarlen, maxline + 4); + w = MIN(w, widget_max_width(conf) - 1); + } + if (rows == BSDDIALOG_AUTOSIZE) { + h = 5; /* borders + mainbar */ + h += nminbars/2; + h += (strlen(text) > 0 ? 3 : 0); + h = MIN(h, widget_max_height(conf) -1); + } - bar = new_boxed_window(conf, y+rows -4, x+3, 3, cols-6, RAISED); + /* mixedgauge checksize */ + if (w < max_minbarlen + 2) + RETURN_ERROR("Few cols for this mixedgauge"); + if (h < 5 + (int)nminbars/2 + (strlen(text) > 0 ? 1 : 0)) + RETURN_ERROR("Few rows for this mixedgauge"); + + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + output = new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, + RAISED, &textpad, &htextpad, text, false); + if (output == BSDDIALOG_ERROR) + return output; /* mini bars */ - for (i=0; i < (argc/2); i++) { - miniperc = atol(argv[i*2 + 1]); + for (i=0; i < (int)nminbars/2; i++) { + miniperc = atol(minibars[i*2 + 1]); if (miniperc == 8) continue; - mvwaddstr(widget, i+1, 2, argv[i*2]); + mvwaddstr(widget, i+1, 2, minibars[i*2]); if (miniperc > 9) - mvwaddstr(widget, i+1, cols-2-15, states[10]); + mvwaddstr(widget, i+1, w-2-15, states[10]); else if (miniperc >= 0 && miniperc <= 9) - mvwaddstr(widget, i+1, cols-2-15, states[miniperc]); + mvwaddstr(widget, i+1, w-2-15, states[miniperc]); else { //miniperc < 0 miniperc = abs(miniperc); - mvwaddstr(widget, i+1, cols-2-15, "[ ]"); - draw_perc_bar(widget, i+1, 1+cols-2-15, 13, miniperc, + mvwaddstr(widget, i+1, w-2-15, "[ ]"); + draw_perc_bar(widget, i+1, 1+w-2-15, 13, miniperc, false, -1 /*unused*/); } } - print_text(conf, widget, rows-6, 2, cols-2, text); - + wrefresh(widget); + ypad = y + h - 5 - htextpad; + ypad = ypad < y+(int)nminbars/2 ? y+nminbars/2 : ypad; + prefresh(textpad, 0, 0, ypad, x+2, y+h-4, x+w-2); + /* main bar */ - draw_perc_bar(bar, 1, 1, cols-8, perc, false, -1 /*unused*/); + bar = new_boxed_window(conf, y+h -4, x+3, 3, w-6, RAISED); + + draw_perc_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/); - wattron(bar, t.barcolor); + wattron(bar, t.bar.color); mvwaddstr(bar, 0, 2, "Overall Progress"); - wattroff(bar, t.barcolor); + wattroff(bar, t.bar.color); - wrefresh(widget); wrefresh(bar); - getch(); + /* getch(); port ncurses shows nothing */ delwin(bar); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return BSDDIALOG_YESOK; } int -bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, int min, - int max, int *value) +bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols, + int min, int max, int *value) { - WINDOW *widget, *bar, *shadow; - int y, x; + WINDOW *widget, *textpad, *bar, *shadow; + int i, y, x, h, w, htextpad; bool loop, buttupdate, barupdate; - int input, currvalue, output, sizebar; + int input, currvalue, output, sizebar, bigchange, positions; float perc; - int positions = max - min + 1; struct buttons bs; - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; + if (value == NULL) + RETURN_ERROR("*value cannot be NULL"); + + if (min >= max) + RETURN_ERROR("min >= max"); - bar = new_boxed_window(conf, y + rows - 6, x +7, 3, cols-14, RAISED); + currvalue = *value; + positions = max - min + 1; get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - if (value == NULL) - RETURN_ERROR("*value == NULL"); - - currvalue = *value; - sizebar = cols - 16; + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0) + return BSDDIALOG_ERROR; + if (bar_checksize(text, h, w, &bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7, + x+w-1-t.text.hmargin); + + sizebar = w - HBORDERS - 2 - BARMARGIN * 2; + bigchange = MAX(1, sizebar/10); + + bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3, + sizebar + 2, RAISED); + loop = buttupdate = barupdate = true; while(loop) { + if (buttupdate) { + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); + buttupdate = false; + } if (barupdate) { - perc = ((float)(currvalue - min)*100) / ((float)positions-1); + perc = ((float)(currvalue - min)*100) / (positions-1); draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue); barupdate = false; wrefresh(bar); } - if (buttupdate) { - draw_buttons(widget, rows-2, cols, bs, true); - wrefresh(widget); - buttupdate = false; - } - input = getch(); switch(input) { - case 10: // Enter - output = bs.value[bs.curr]; // values -> outputs + case KEY_ENTER: + case 10: /* Enter */ + output = bs.value[bs.curr]; *value = currvalue; loop = false; break; @@ -244,7 +389,7 @@ bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, i output = BSDDIALOG_ESC; loop = false; break; - case '\t': // TAB + case '\t': /* TAB */ bs.curr = (bs.curr + 1) % bs.nbuttons; buttupdate = true; break; @@ -260,6 +405,26 @@ bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, i buttupdate = true; } break; + case KEY_HOME: + currvalue = max; + barupdate = true; + break; + case KEY_END: + currvalue = min; + barupdate = true; + break; + case KEY_NPAGE: + currvalue -= bigchange; + if (currvalue < min) + currvalue = min; + barupdate = true; + break; + case KEY_PPAGE: + currvalue += bigchange; + if (currvalue > max) + currvalue = max; + barupdate = true; + break; case KEY_UP: if (currvalue < max) { currvalue++; @@ -272,58 +437,132 @@ bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, i barupdate = true; } break; + case KEY_F(1): + if (conf->hfile == NULL) + break; + if (f1help(conf) != 0) + return BSDDIALOG_ERROR; + /* No break! the terminal size can change */ + case KEY_RESIZE: + hide_widget(y, x, h, w,conf->shadow); + + /* + * Unnecessary, but, when the columns decrease the + * following "refresh" seem not work + */ + refresh(); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0) + return BSDDIALOG_ERROR; + if (bar_checksize(text, h, w, &bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + wclear(shadow); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); + wresize(shadow, h, w); + + wclear(widget); + mvwin(widget, y, x); + wresize(widget, h, w); + + htextpad = 1; + wclear(textpad); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); + + sizebar = w - HBORDERS - 2 - BARMARGIN * 2; + bigchange = MAX(1, sizebar/10); + wclear(bar); + mvwin(bar, y + h - 6, x + 1 + BARMARGIN); + wresize(bar, 3, sizebar + 2); + + if(update_widget_withtextpad(conf, shadow, widget, h, w, + RAISED, textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7, + x+w-1-t.text.hmargin); + + draw_borders(conf, bar, 3, sizebar + 2, RAISED); + + barupdate = true; + buttupdate = true; + break; + default: + for (i = 0; i < (int) bs.nbuttons; i++) + if (tolower(input) == tolower((bs.label[i])[0])) { + output = bs.value[i]; + loop = false; + } } } delwin(bar); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } -int bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols, int sec) +int +bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int sec) { - WINDOW *widget, *bar, *shadow; - int output, y, x; + WINDOW *widget, *textpad, *bar, *shadow; + int i, output, y, x, h, w, htextpad; bool loop, buttupdate, barupdate; - int input, currvalue, sizebar; + int input, tout, sizebar; float perc; struct buttons bs; - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; - - bar = new_boxed_window(conf, y + rows - 6, x +7, 3, cols-14, RAISED); - get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - currvalue = sec; - sizebar = cols-16; + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0) + return BSDDIALOG_ERROR; + if (bar_checksize(text, h, w, &bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7, + x+w-1-t.text.hmargin); + + sizebar = w - HBORDERS - 2 - BARMARGIN * 2; + bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3, + sizebar + 2, RAISED); + + tout = sec; nodelay(stdscr, TRUE); timeout(1000); - //wtimeout(buttwin, 2); loop = buttupdate = barupdate = true; while(loop) { if (barupdate) { - perc = ((float)(currvalue*100)) / ((float)sec); - draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue); + perc = (float)tout * 100 / sec; + draw_perc_bar(bar, 1, 1, sizebar, perc, true, tout); barupdate = false; wrefresh(bar); } if (buttupdate) { - draw_buttons(widget, rows-2, cols, bs, true); + draw_buttons(widget, h-2, w, bs, true); wrefresh(widget); buttupdate = false; } input = getch(); - if(input < 0) { - currvalue--; - if (currvalue < 0) { - output = BSDDIALOG_ERROR; + if(input < 0) { /* timeout */ + tout--; + if (tout < 0) { + output = BSDDIALOG_TIMEOUT; break; } else { @@ -332,15 +571,16 @@ int bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols, } } switch(input) { - case 10: // Enter - output = bs.value[bs.curr]; // values -> outputs + case KEY_ENTER: + case 10: /* Enter */ + output = bs.value[bs.curr]; loop = false; break; case 27: /* Esc */ output = BSDDIALOG_ESC; loop = false; break; - case '\t': // TAB + case '\t': /* TAB */ bs.curr = (bs.curr + 1) % bs.nbuttons; buttupdate = true; break; @@ -356,14 +596,72 @@ int bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols, buttupdate = true; } break; + case KEY_F(1): + if (conf->hfile == NULL) + break; + if (f1help(conf) != 0) + return BSDDIALOG_ERROR; + /* No break! the terminal size can change */ + case KEY_RESIZE: + hide_widget(y, x, h, w,conf->shadow); + + /* + * Unnecessary, but, when the columns decrease the + * following "refresh" seem not work + */ + refresh(); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0) + return BSDDIALOG_ERROR; + if (bar_checksize(text, h, w, &bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + wclear(shadow); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); + wresize(shadow, h, w); + + wclear(widget); + mvwin(widget, y, x); + wresize(widget, h, w); + + htextpad = 1; + wclear(textpad); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); + + sizebar = w - HBORDERS - 2 - BARMARGIN * 2; + wclear(bar); + mvwin(bar, y + h - 6, x + 1 + BARMARGIN); + wresize(bar, 3, sizebar + 2); + + if(update_widget_withtextpad(conf, shadow, widget, h, w, + RAISED, textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7, + x+w-1-t.text.hmargin); + + draw_borders(conf, bar, 3, sizebar + 2, RAISED); + + barupdate = true; + buttupdate = true; + break; + default: + for (i = 0; i < (int) bs.nbuttons; i++) + if (tolower(input) == tolower((bs.label[i])[0])) { + output = bs.value[i]; + loop = false; + } } } nodelay(stdscr, FALSE); delwin(bar); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } - diff --git a/lib/bsddialog.3 b/lib/bsddialog.3 new file mode 100644 index 000000000000..7e1238f38e52 --- /dev/null +++ b/lib/bsddialog.3 @@ -0,0 +1,42 @@ +.Dd $Mdocdate$ +.Dt PROGNAME section +.Os +.Sh NAME +.Nm progname +.Nd one line about what it does +.\" .Sh LIBRARY +.\" For sections 2, 3, and 9 only. +.\" Not used in OpenBSD. +.Sh SYNOPSIS +.Nm progname +.Op Fl options +.Ar +.Sh DESCRIPTION +The +.Nm +utility processes files ... +.\" .Sh CONTEXT +.\" For section 9 functions only. +.\" .Sh IMPLEMENTATION NOTES +.\" Not used in OpenBSD. +.\" .Sh RETURN VALUES +.\" For sections 2, 3, and 9 function return values only. +.\" .Sh ENVIRONMENT +.\" For sections 1, 6, 7, and 8 only. +.\" .Sh FILES +.\" .Sh EXIT STATUS +.\" For sections 1, 6, and 8 only. +.\" .Sh EXAMPLES +.\" .Sh DIAGNOSTICS +.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. +.\" .Sh ERRORS +.\" For sections 2, 3, 4, and 9 errno settings only. +.\" .Sh SEE ALSO +.\" .Xr foobar 1 +.\" .Sh STANDARDS +.\" .Sh HISTORY +.\" .Sh AUTHORS +.\" .Sh CAVEATS +.\" .Sh BUGS +.\" .Sh SECURITY CONSIDERATIONS +.\" Not used in OpenBSD. diff --git a/lib/bsddialog.h b/lib/bsddialog.h index e6c2cc67f581..de6dc100b8c3 100644 --- a/lib/bsddialog.h +++ b/lib/bsddialog.h @@ -25,11 +25,13 @@ * SUCH DAMAGE. */ -#ifndef _BSDDIALOG_H_ -#define _BSDDIALOG_H_ +#ifndef _LIBBSDDIALOG_H_ +#define _LIBBSDDIALOG_H_ #include <stdbool.h> +#define LIBBSDDIALOG_VERSION "0.1-devel" + /* Exit status */ #define BSDDIALOG_ERROR -1 #define BSDDIALOG_YESOK 0 @@ -37,7 +39,10 @@ #define BSDDIALOG_HELP 2 #define BSDDIALOG_EXTRA 3 #define BSDDIALOG_ITEM_HELP 4 -#define BSDDIALOG_ESC 5 +#define BSDDIALOG_TIMEOUT 5 +#define BSDDIALOG_ESC 6 +#define BSDDIALOG_GENERIC1 7 +#define BSDDIALOG_GENERIC2 8 /* size and position */ #define BSDDIALOG_FULLSCREEN -1 @@ -45,55 +50,40 @@ #define BSDDIALOG_CENTER -1 struct bsddialog_conf { - /* conf.* */ bool ascii_lines; - int aspect_ratio; - int x; - int y; + int aspect_ratio; + int x; + int y; bool clear; - int *get_height; - int *get_width; + int *get_height; + int *get_width; char *hfile; char *hline; - /*int input_fd;*/ - /*bool keep_tite;*/ - /*bool keep_window;*/ - /*bool last_key;*/ - /*int max_input;*/ - /*bool no_kill;*/ bool no_lines; - /*bool no_mouse; useful?*/ - /*bool scrollbar; useful?*/ - /*char *separate_witget;*/ bool shadow; - /*bool size_err;*/ - int sleep; - /*int timeout;*/ + int sleep; char *title; - /* conf.text.* */ + struct { bool colors; + /* following members could be deleted in the future */ bool cr_wrap; bool no_collapse; bool no_nl_expand; - /*bool tab_correct; textbox?*/ - /*int tab_len; textbox?*/ bool trim; } text; - /* conf.form.* */ - /*struct { - bool insecure; - } form;*/ - /* conf.menu.* */ + struct { bool align_left; - char *colums_separator; - char *default_item; /*delete, add int *focus to API?*/ - bool no_items; - bool no_tags; - /*bool visit_items;*/ + char *default_item; + bool no_desc; + bool no_name; } menu; - /* conf.button.* */ + + struct { + int securech; + } form; + struct { char *cancel_label; bool defaultno; @@ -101,6 +91,8 @@ struct bsddialog_conf { char *exit_label; bool extra_button; char *extra_label; + char *generic1_label; + char *generic2_label; bool help_button; char *help_label; bool no_cancel; @@ -113,8 +105,8 @@ struct bsddialog_conf { struct bsddialog_menuitem { char *prefix; - bool on; - int depth; + bool on; + int depth; char *name; char *desc; char *bottomdesc; @@ -132,126 +124,97 @@ struct bsddialog_menugroup { struct bsddialog_menuitem *items; }; +struct bsddialog_formitem { + char *label; + unsigned int ylabel; + unsigned int xlabel; + + char *init; + unsigned int yfield; + unsigned int xfield; + unsigned int fieldlen; + unsigned int maxvaluelen; + char *value; /* allocated memory */ +#define BSDDIALOG_FIELDHIDDEN 0x1 +#define BSDDIALOG_FIELDREADONLY 0x2 + unsigned int flags; + + char *bottomdesc; /* unimplemented for now */ +}; + int bsddialog_init(void); int bsddialog_end(void); -int bsddialog_backtitle(struct bsddialog_conf conf, char *backtitle); +int bsddialog_backtitle(struct bsddialog_conf *conf, char *backtitle); const char *bsddialog_geterror(void); +void bsddialog_initconf(struct bsddialog_conf *conf); +/* funcs for tzsetup(8), they will be deleted */ int bsddialog_terminalheight(void); int bsddialog_terminalwidth(void); -void bsddialog_initconf(struct bsddialog_conf *conf); /* widgets */ int -bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem); int -bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int *yy, unsigned int *mm, unsigned int *dd); - -int -bsddialog_checklist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem); int -bsddialog_dselect(struct bsddialog_conf conf, char* text, int rows, int cols); - -int -bsddialog_editbox(struct bsddialog_conf conf, char* text, int rows, int cols); - -int bsddialog_form(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int argc, char **argv); - -int -bsddialog_fselect(struct bsddialog_conf conf, char* text, int rows, int cols); - -int -bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols, - int perc); +bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int *yy, unsigned int *mm, unsigned int *dd); int -bsddialog_infobox(struct bsddialog_conf conf, char* text, int rows, int cols); +bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int formheight, unsigned int nitems, + struct bsddialog_formitem *items); int -bsddialog_inputbox(struct bsddialog_conf conf, char* text, int rows, int cols); +bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int perc); int -bsddialog_inputmenu(struct bsddialog_conf conf, char* text, int rows, int cols); +bsddialog_infobox(struct bsddialog_conf *conf, char* text, int rows, int cols); int -bsddialog_menu(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem); int -bsddialog_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int argc, char **argv); +bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int mainperc, unsigned int nminbars, char **minibars); int -bsddialog_mixedgauge(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int perc, int argc, char **argv); - -int -bsddialog_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups, int *focuslist, int *focusitem); int -bsddialog_msgbox(struct bsddialog_conf conf, char* text, int rows, int cols); - -int -bsddialog_passwordbox(struct bsddialog_conf conf, char* text, int rows, - int cols); - -int -bsddialog_passwordform(struct bsddialog_conf conf, char* text, int rows, - int cols, int formheight, int argc, char **argv); - -int -bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols, - int sec); - -int -bsddialog_prgbox(struct bsddialog_conf conf, char* text, int rows, int cols, - char *command); +bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols); int -bsddialog_programbox(struct bsddialog_conf conf, char* text, int rows, - int cols); +bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int sec); int -bsddialog_progressbox(struct bsddialog_conf conf, char* text, int rows, - int cols); - -int -bsddialog_radiolist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem); int -bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols, int min, int max, int *value); int -bsddialog_tailbox(struct bsddialog_conf conf, char* text, int rows, int cols); - -int -bsddialog_tailboxbg(struct bsddialog_conf conf, char* text, int rows, int cols); - -int -bsddialog_textbox(struct bsddialog_conf conf, char* text, int rows, int cols); +bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols); int -bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss); -int -bsddialog_treeview(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int menurows, int nitems, struct bsddialog_menuitem *items, - int *focusitem); - -int bsddialog_yesno(struct bsddialog_conf conf, char* text, int rows, int cols); +int bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols); #endif diff --git a/lib/bsddialog_theme.h b/lib/bsddialog_theme.h index b39b8840bce8..de44b456576a 100644 --- a/lib/bsddialog_theme.h +++ b/lib/bsddialog_theme.h @@ -39,45 +39,63 @@ enum bsddialog_color { BSDDIALOG_WHITE, }; +/* f_ for focus/selected/active/current element */ struct bsddialog_theme { - int shadowcolor; - unsigned int shadowrows; - unsigned int shadowcols; + struct { + int color; + } terminal; - int backgroundcolor; - bool surroundtitle; - int titlecolor; - int lineraisecolor; - int linelowercolor; - int widgetcolor; + struct { + int color; + unsigned int h; + unsigned int w; + } shadow; - unsigned int texthmargin; + struct { + int color; + bool delimtitle; + int titlecolor; + int lineraisecolor; + int linelowercolor; + int bottomtitlecolor; + } widget; - int curritemcolor; - int itemcolor; - int currtagcolor; - int tagcolor; - int namesepcolor; - int descsepcolor; + struct { + unsigned int hmargin; + } text; - int currfieldcolor; - int fieldcolor; - int fieldreadonlycolor; + struct { + int arrowcolor; + int f_namecolor; + int namecolor; + int f_desccolor; + int desccolor; + int namesepcolor; + int descsepcolor; + } menu; - int currbarcolor; - int barcolor; + struct { + int f_fieldcolor; + int fieldcolor; + int readonlycolor; + } form; - unsigned int buttonspace; - int buttleftch; - int buttrightchar; - int currbuttdelimcolor; - int buttdelimcolor; - int currbuttoncolor; - int buttoncolor; - int currshortkeycolor; - int shortkeycolor; + struct { + int f_color; + int color; + } bar; - int bottomtitlecolor; + struct { + unsigned int space; + int leftch; + int rightch; + int delimcolor; + int f_delimcolor; + int color; + int f_color; + int shortcutcolor; + int f_shortcutcolor; + } button; }; enum bsddialog_default_theme { @@ -85,11 +103,12 @@ enum bsddialog_default_theme { BSDDIALOG_THEME_BSDDIALOG, BSDDIALOG_THEME_DEFAULT, BSDDIALOG_THEME_DIALOG, - BSDDIALOG_THEME_MAGENTA, }; -int bsddialog_color(enum bsddialog_color background, enum bsddialog_color foreground); -struct bsddialog_theme bsddialog_get_theme(); +int +bsddialog_color(enum bsddialog_color background, + enum bsddialog_color foreground); +struct bsddialog_theme bsddialog_get_theme(void); void bsddialog_set_theme(struct bsddialog_theme theme); int bsddialog_set_default_theme(enum bsddialog_default_theme theme); diff --git a/lib/commandbox.c b/lib/commandbox.c deleted file mode 100644 index e5d65166e230..000000000000 --- a/lib/commandbox.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2021 Alfonso Sabato Siciliano - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <unistd.h> - -#ifdef PORTNCURSES -#include <ncurses/curses.h> -#else -#include <curses.h> -#endif - -#include "bsddialog.h" -#include "lib_util.h" -#include "bsddialog_theme.h" - -/* "Command": prgbox - programbox - progressbox */ - -#define MAXINPUT 2048 /* in bsddialoh.h? in bsddialog.c get/set static maxinput? */ - -extern struct bsddialog_theme t; - -static int -command_handler(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey) -{ - bool loop, update; - int i, input; - int output; - - loop = update = true; - while(loop) { - if (update) { - draw_buttons(window, y, cols, bs, shortkey); - update = false; - } - wrefresh(window); - input = getch(); - switch (input) { - case 10: /* Enter */ - output = bs.value[bs.curr]; - loop = false; - break; - case 27: /* Esc */ - output = BSDDIALOG_ESC; - loop = false; - break; - case '\t': /* TAB */ - bs.curr = (bs.curr + 1) % bs.nbuttons; - update = true; - break; - case KEY_LEFT: - if (bs.curr > 0) { - bs.curr--; - update = true; - } - break; - case KEY_RIGHT: - if (bs.curr < (int) bs.nbuttons - 1) { - bs.curr++; - update = true; - } - break; - default: - if (shortkey) { - for (i = 0; i < (int) bs.nbuttons; i++) - if (input == (bs.label[i])[0]) { - output = bs.value[i]; - loop = false; - } - } - } - } - - return output; -} - -int -bsddialog_prgbox(struct bsddialog_conf conf, char* text, int rows, int cols, char *command) -{ - char line[MAXINPUT]; - WINDOW *widget, *pad, *shadow; - int i, y, x, padrows, padcols, ys, ye, xs, xe; - int output; - int pipefd[2]; - struct buttons bs; - - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; - - get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), - NULL, BUTTONLABEL(help_label)); - - if (text != NULL && conf.no_lines == false) { - print_text(conf, widget, 1, 1, cols-2, text); - mvwhline(widget, 2, 2, conf.ascii_lines ? '-' : ACS_HLINE, cols -4); - wrefresh(widget); - } - - padrows = text == NULL ? rows - 4 : rows - 6; - padcols = cols - 2; - ys = text == NULL ? y + 1 : y + 3; - xs = x + 1; - ye = ys + padrows; - xe = xs + padcols; - - pad = newpad(padrows, padcols); - wbkgd(pad, t.widgetcolor); - - pipe(pipefd); - if (fork() == 0) - { - close(pipefd[0]); // close reading - - dup2(pipefd[1], 1); // send stdout to the pipe - dup2(pipefd[1], 2); // send stderr to the pipe - - close(pipefd[1]); // this descriptor is no longer needed - - //const char *ls="/bin/ls"; - execl(command, command, NULL); - return 0; - } - else - { - close(pipefd[1]); // close write - - i = 0; - while (read(pipefd[0], line, MAXINPUT) != 0) { - mvwaddstr(pad, i, 0, line); - prefresh(pad, 0, 0, ys, xs, ye, xe); - i++; - } - } - - output = command_handler(widget, rows-2, cols, bs, true); - - return output; -} - -int bsddialog_programbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - char line[MAXINPUT]; - WINDOW *widget, *pad, *shadow; - int i, y, x, padrows, padcols, ys, ye, xs, xe, output; - struct buttons bs; - - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; - - get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), - BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - - if (text != NULL && conf.no_lines == false) { - mvwhline(widget, 2, 2, conf.ascii_lines ? '-' : ACS_HLINE, cols -4); - wrefresh(widget); - } - - padrows = text == NULL ? rows - 4 : rows - 6; - padcols = cols - 2; - ys = text == NULL ? y + 1 : y + 3; - xs = x + 1; - ye = ys + padrows; - xe = xs + padcols; - - pad = newpad(padrows, padcols); - - i = 0; - //while (fgets(line, MAXINPUT, stdin) != NULL) { - while(getstr(line) != ERR){ - mvwaddstr(pad, i, 0, line); - prefresh(pad, 0, 0, ys, xs, ye, xe); - i++; - } - - output = command_handler(widget, rows-2, cols, bs, true); - - return output; -} - -int bsddialog_progressbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - text = "Progressbox unimplemented"; - bsddialog_msgbox(conf, text, rows, cols); - RETURN_ERROR(text); -} - diff --git a/lib/editorbox.c b/lib/editorbox.c deleted file mode 100644 index b0f57908aa0e..000000000000 --- a/lib/editorbox.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2021 Alfonso Sabato Siciliano - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef PORTNCURSES -#include <ncurses/curses.h> -#else -#include <curses.h> -#endif - -#include "bsddialog.h" -#include "lib_util.h" - -/* "Editor": editbox */ - -int bsddialog_editbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - text = "Editbox unimplemented"; - bsddialog_msgbox(conf, text, rows, cols); - RETURN_ERROR(text); -} - diff --git a/lib/filebox.c b/lib/filebox.c deleted file mode 100644 index b951f4e0d0f0..000000000000 --- a/lib/filebox.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2021 Alfonso Sabato Siciliano - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef PORTNCURSES -#include <ncurses/curses.h> -#else -#include <curses.h> -#endif - -#include "bsddialog.h" -#include "lib_util.h" - -/* "File": dselect - fselect */ - -int bsddialog_dselect(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - text = "Dselect unimplemented"; - bsddialog_msgbox(conf, text, rows, cols); - RETURN_ERROR(text); -} - -int bsddialog_fselect(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - text = "Fselect unimplemented"; - bsddialog_msgbox(conf, text, rows, cols); - RETURN_ERROR(text); -} - diff --git a/lib/formbox.c b/lib/formbox.c index f636db7990dd..70e7d9498b90 100644 --- a/lib/formbox.c +++ b/lib/formbox.c @@ -25,13 +25,15 @@ * SUCH DAMAGE. */ +#include <sys/param.h> + +#include <ctype.h> #include <stdlib.h> +#include <string.h> #ifdef PORTNCURSES -#include <ncurses/curses.h> #include <ncurses/form.h> #else -#include <curses.h> #include <form.h> #endif @@ -39,82 +41,111 @@ #include "lib_util.h" #include "bsddialog_theme.h" +#define REDRAWFORM 14021986 /* magic number */ +#define ISFIELDHIDDEN(item) (item.flags & BSDDIALOG_FIELDHIDDEN) +#define ISFIELDREADONLY(item) (item.flags & BSDDIALOG_FIELDREADONLY) + /* "Form": inputbox - passwordbox - form - passwordform - mixedform */ extern struct bsddialog_theme t; -int bsddialog_inputmenu(struct bsddialog_conf conf, char* text, int rows, int cols) +/* util struct for private buffer and view options */ +struct myfield { + int len; + char *buf; + int pos; + int size; + bool secure; + int securech; +}; +#define GETMYFIELD(field) ((struct myfield*)field_userptr(field)) +#define GETMYFIELD2(form) ((struct myfield*)field_userptr(current_field(form))) + +static void insertch(struct myfield *mf, int ch) { - text = "Inputbox unimplemented"; - bsddialog_msgbox(conf, text, rows, cols); - RETURN_ERROR(text); + int i; + + if (mf->len == mf->size) + return; + + for (i=mf->len-1; i>=mf->pos; i--) { + mf->buf[i+1] = mf->buf[i]; + } + + mf->buf[mf->pos] = ch; + mf->pos += 1; + mf->len += 1; + mf->buf[mf->len] = '\0'; } -#define ITEMHIDDEN 0x1 -#define ISITEMHIDDEN(item) (item.itemflags & 0x1) -#define ITEMREADONLY 0x2 -#define ISITEMREADONLY(item) (item.itemflags & 0x2) -struct formitem { - char *label; - unsigned int ylabel; - unsigned int xlabel; - char *item; - unsigned int yitem; - unsigned int xitem; - int itemlen; - unsigned int inputlen; - unsigned int itemflags; -}; +static void shiftleft(struct myfield *mf) +{ + int i, last; + + for (i=mf->pos; i<mf->len; i++) { + mf->buf[i] = mf->buf[i+1]; + } + + last = mf->len > 0 ? mf->len -1 : 0; + mf->buf[last] = '\0'; + mf->len = last; +} static int -mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs, - bool shortkey, WINDOW *entry, FORM *form, FIELD **field, int nitems - /*struct formitem *items*/) +form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, + struct buttons bs, WINDOW *formwin, FORM *form, FIELD **cfield, int nitems, + struct bsddialog_formitem *items) { - bool loop, buttupdate, inentry = true; - int input, output; + bool loop, buttupdate, informwin = true; + int i, input, output; + struct myfield *mf; curs_set(2); pos_form_cursor(form); loop = buttupdate = true; bs.curr = -1; + form_driver(form, REQ_END_LINE); + form_driver(form, REQ_END_LINE); + mf = GETMYFIELD2(form); + mf->pos = mf->len; while(loop) { if (buttupdate) { - draw_buttons(widget, y, cols, bs, shortkey); + draw_buttons(widget, y, cols, bs, !informwin); wrefresh(widget); buttupdate = false; } - wrefresh(entry); + wrefresh(formwin); input = getch(); switch(input) { - case 10: // Enter - if (inentry) + case KEY_ENTER: + case 10: /* Enter */ + if (informwin) break; - output = bs.value[bs.curr]; // values -> buttvalues - form_driver(form, REQ_NEXT_FIELD); - form_driver(form, REQ_PREV_FIELD); - /* add a struct for forms */ - /*for (i=0; i<nitems; i++) { - bufp = field_buffer(field[i], 0); - dprintf(fd, "\n+%s", bufp); - bufp = field_buffer(field[i], 1); - dprintf(fd, "-%s+", bufp); - }*/ + output = bs.value[bs.curr]; + if (output == BSDDIALOG_YESOK) { + form_driver(form, REQ_NEXT_FIELD); + form_driver(form, REQ_PREV_FIELD); + for (i=0; i<nitems; i++) { + mf = GETMYFIELD(cfield[i]); + items[i].value = strdup(mf->buf); + } + } loop = false; break; case 27: /* Esc */ output = BSDDIALOG_ESC; loop = false; break; - case '\t': // TAB - if (inentry) { + case '\t': /* TAB */ + if (informwin) { bs.curr = 0; - inentry = false; + informwin = false; curs_set(0); } else { bs.curr++; - inentry = bs.curr >= (int) bs.nbuttons ? true : false; - if (inentry) { + informwin = bs.curr >= (int) bs.nbuttons ? + true : false; + if (informwin) { curs_set(2); pos_form_cursor(form); } @@ -122,8 +153,11 @@ mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs, buttupdate = true; break; case KEY_LEFT: - if (inentry) { + if (informwin) { form_driver(form, REQ_PREV_CHAR); + mf = GETMYFIELD2(form); + if (mf->pos > 0) + mf->pos -= 1; } else { if (bs.curr > 0) { bs.curr--; @@ -132,7 +166,11 @@ mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs, } break; case KEY_RIGHT: - if (inentry) { + if (informwin) { + mf = GETMYFIELD2(form); + if (mf->pos >= mf->len) + break; + mf->pos += 1; form_driver(form, REQ_NEXT_CHAR); } else { if (bs.curr < (int) bs.nbuttons - 1) { @@ -144,32 +182,73 @@ mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs, case KEY_UP: if (nitems < 2) break; - set_field_fore(current_field(form), t.fieldcolor); - set_field_back(current_field(form), t.fieldcolor); + set_field_fore(current_field(form), t.form.fieldcolor); + set_field_back(current_field(form), t.form.fieldcolor); form_driver(form, REQ_PREV_FIELD); form_driver(form, REQ_END_LINE); - set_field_fore(current_field(form), t.currfieldcolor); - set_field_back(current_field(form), t.currfieldcolor); + mf = GETMYFIELD2(form); + mf->pos = mf->len; + set_field_fore(current_field(form), t.form.f_fieldcolor); + set_field_back(current_field(form), t.form.f_fieldcolor); break; case KEY_DOWN: if (nitems < 2) break; - set_field_fore(current_field(form), t.fieldcolor); - set_field_back(current_field(form), t.fieldcolor); + set_field_fore(current_field(form), t.form.fieldcolor); + set_field_back(current_field(form), t.form.fieldcolor); form_driver(form, REQ_NEXT_FIELD); form_driver(form, REQ_END_LINE); - set_field_fore(current_field(form), t.currfieldcolor); - set_field_back(current_field(form), t.currfieldcolor); + mf = GETMYFIELD2(form); + mf->pos = mf->len; + set_field_fore(current_field(form), t.form.f_fieldcolor); + set_field_back(current_field(form), t.form.f_fieldcolor); break; case KEY_BACKSPACE: + case 127: /* Backspace */ + mf = GETMYFIELD2(form); + if (mf->pos <= 0) + break; form_driver(form, REQ_DEL_PREV); + mf = GETMYFIELD2(form); + mf->pos -= 1; + shiftleft(mf); break; case KEY_DC: form_driver(form, REQ_DEL_CHAR); + mf = GETMYFIELD2(form); + if (mf->len-1 >= mf->pos) + shiftleft(mf); + break; + case KEY_F(1): + if (conf->hfile == NULL) + break; + if (f1help(conf) != 0) + return BSDDIALOG_ERROR; + /* No Break */ + case KEY_RESIZE: + output = REDRAWFORM; + loop = false; break; default: - if (inentry) { - form_driver(form, input); + /* + * user input, add unicode chars to "public" buffer + */ + if (informwin) { + mf = GETMYFIELD2(form); + if (mf->secure) + form_driver(form, mf->securech); + else + form_driver(form, input); + insertch(mf, input); + } + else { + for (i = 0; i < (int) bs.nbuttons; i++) { + if (tolower(input) == + tolower((bs.label[i])[0])) { + output = bs.value[i]; + loop = false; + } + } } break; } @@ -180,217 +259,214 @@ mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs, return output; } -static int -do_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int nitems, struct formitem *items) +static void +form_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, + char *text, int linelen, unsigned int *formheight, int nitems, + struct buttons bs) { - WINDOW *widget, *entry, *shadow; - int i, output, color, y, x; - FIELD **field; - FORM *form; - struct buttons bs; - - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; - - entry = new_boxed_window(conf, y + rows - 3 - formheight -2, x +1, - formheight+2, cols-2, LOWERED); + int textrow, menusize; + + textrow = text != NULL && strlen(text) > 0 ? 1 : 0; + + if (cols == BSDDIALOG_AUTOSIZE) { + *w = VBORDERS; + /* buttons size */ + *w += bs.nbuttons * bs.sizebutton; + *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; + /* line size */ + *w = MAX(*w, linelen + 3); + /* + * avoid terminal overflow, + * -1 fix false negative with big menu over the terminal and + * autosize, for example "portconfig /usr/ports/www/apache24/". + */ + *w = MIN(*w, widget_max_width(conf)-1); + } - get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), - BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); + if (rows == BSDDIALOG_AUTOSIZE) { + *h = HBORDERS + 2 /* buttons */ + textrow; - field = calloc(nitems + 1, sizeof(FIELD*)); - for (i=0; i < nitems; i++) { - field[i] = new_field(1, items[i].itemlen, items[i].yitem-1, items[i].xitem-1, 0, 1); - field_opts_off(field[i], O_STATIC); - set_max_field(field[i], items[i].inputlen); - set_field_buffer(field[i], 0, items[i].item); - set_field_buffer(field[i], 1, items[i].item); - field_opts_off(field[i], O_AUTOSKIP); - field_opts_off(field[i], O_BLANK); - //field_opts_off(field[i], O_BS_OVERLOAD); - - if (ISITEMHIDDEN(items[i])) - field_opts_off(field[i], O_PUBLIC); - - if (ISITEMREADONLY(items[i])) { - field_opts_off(field[i], O_EDIT); - field_opts_off(field[i], O_ACTIVE); - color = t.fieldreadonlycolor; - } else { - color = i == 0 ? t.currfieldcolor : t.fieldcolor; + if (*formheight == 0) { + *h += nitems + 2; + *h = MIN(*h, widget_max_height(conf)); + menusize = MIN(nitems + 2, *h - (HBORDERS + 2 + textrow)); + menusize -=2; + *formheight = menusize < 0 ? 0 : menusize; } - set_field_fore(field[i], color); - set_field_back(field[i], color); - } - field[i] = NULL; + else /* h autosize with a fixed formheight */ + *h = *h + *formheight + 2; - if (nitems == 1) {// inputbox or passwordbox - set_field_fore(field[0], t.widgetcolor); - set_field_back(field[0], t.widgetcolor); + /* avoid terminal overflow */ + *h = MIN(*h, widget_max_height(conf)); } + else { + if (*formheight == 0) + *formheight = MIN(rows-6-textrow, nitems); + } +} - form = new_form(field); - set_form_win(form, entry); - set_form_sub(form, derwin(entry, nitems, cols-4, 1, 1)); - post_form(form); +static int +form_checksize(int rows, int cols, char *text, int formheight, int nitems, + struct buttons bs) +{ + int mincols, textrow, formrows; - for (i=0; i < nitems; i++) - mvwaddstr(entry, items[i].ylabel, items[i].xlabel, items[i].label); + mincols = VBORDERS; + /* buttons */ + mincols += bs.nbuttons * bs.sizebutton; + mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; + /* line, comment to permet some cols hidden */ + /* mincols = MAX(mincols, linelen); */ - wrefresh(entry); + if (cols < mincols) + RETURN_ERROR("Few cols, width < size buttons or "\ + "labels + forms"); - output = mixedform_handler(widget, rows-2, cols, bs, true, entry, form, - field, nitems /*,items*/); + textrow = text != NULL && strlen(text) > 0 ? 1 : 0; - unpost_form(form); - free_form(form); - for (i=0; i < nitems; i++) - free_field(field[i]); - free(field); + if (nitems > 0 && formheight == 0) + RETURN_ERROR("fields > 0 but formheight == 0, probably "\ + "terminal too small"); - delwin(entry); - end_widget(conf, widget, rows, cols, shadow); + formrows = nitems > 0 ? 3 : 0; + if (rows < 2 + 2 + formrows + textrow) + RETURN_ERROR("Few lines for this menus"); - return output; + return 0; } -int bsddialog_inputbox(struct bsddialog_conf conf, char* text, int rows, int cols) +int +bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int formheight, unsigned int nitems, + struct bsddialog_formitem *items) { - int output; - struct formitem item; - - item.label = ""; - item.ylabel = 0; - item.xlabel = 0; - item.item = ""; // TODO add argv - item.yitem = 1; - item.xitem = 1; - item.itemlen = cols-4; - item.inputlen = 2048; // todo conf.sizeinput - item.itemflags = 0; - - output = do_mixedform(conf, text, rows, cols, 1, 1, &item); - - return output; -} + WINDOW *widget, *formwin, *textpad, *shadow; + int i, output, color, y, x, h, w, htextpad; + FIELD **cfield; + FORM *form; + struct buttons bs; + struct myfield *myfields; + unsigned long maxline; + + /* disable form scrolling like dialog */ + if (formheight < nitems) + formheight = nitems; + + maxline = 0; + myfields = malloc(nitems * sizeof(struct myfield)); + cfield = calloc(nitems + 1, sizeof(FIELD*)); + for (i=0; i < (int)nitems; i++) { + cfield[i] = new_field(1, items[i].fieldlen, items[i].yfield-1, + items[i].xfield-1, 0, 0); + field_opts_off(cfield[i], O_STATIC); + set_max_field(cfield[i], items[i].maxvaluelen); + set_field_buffer(cfield[i], 0, items[i].init); + + myfields[i].pos = strlen(items[i].init); + myfields[i].len = strlen(items[i].init); + myfields[i].size = items[i].maxvaluelen; + myfields[i].buf = malloc(myfields[i].size); + memset(myfields[i].buf, 0, myfields[i].size); + strcpy(myfields[i].buf, items[i].init); + set_field_userptr(cfield[i], &myfields[i]); + + field_opts_off(cfield[i], O_AUTOSKIP); + field_opts_off(cfield[i], O_BLANK); + /* field_opts_off(field[i], O_BS_OVERLOAD); */ + + if (ISFIELDHIDDEN(items[i])) { + /* field_opts_off(field[i], O_PUBLIC); old hidden */ + myfields[i].secure = true; + myfields[i].securech = ' '; + if (conf->form.securech != '\0') + myfields[i].securech = conf->form.securech; + } + else myfields[i].secure = false; -int bsddialog_passwordbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - int output; - struct formitem item; + if (ISFIELDREADONLY(items[i])) { + field_opts_off(cfield[i], O_EDIT); + field_opts_off(cfield[i], O_ACTIVE); + color = t.form.readonlycolor; + } else { + color = i == 0 ? t.form.f_fieldcolor : t.form.fieldcolor; + } + set_field_fore(cfield[i], color); + set_field_back(cfield[i], color); - item.label = ""; - item.ylabel = 0; - item.xlabel = 0; - item.item = ""; // TODO add argv - item.yitem = 1; - item.xitem = 1; - item.itemlen = cols-4; - item.inputlen = 2048; // todo conf.sizeinput - item.itemflags = ITEMHIDDEN; + maxline = MAX(maxline, items[i].xlabel + strlen(items[i].label)); + maxline = MAX(maxline, items[i].xfield + items[i].fieldlen); + } + cfield[i] = NULL; - output = do_mixedform(conf, text, rows, cols, 1, 1, &item); + /* disable focus with 1 item (inputbox or passwordbox) */ + if (formheight == 1 && nitems == 1 && strlen(items[0].label) == 0 && + items[0].xfield == 1 ) { + set_field_fore(cfield[0], t.widget.color); + set_field_back(cfield[0], t.widget.color); + } + + get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), + BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - return output; -} + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + form_autosize(conf, rows, cols, &h, &w, text, maxline, &formheight, + nitems, bs); + if (form_checksize(h, w, text, formheight, nitems, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, + y + h - formheight, x + 1 + w - t.text.hmargin); + + formwin = new_boxed_window(conf, y + h - 3 - formheight -2, x +1, + formheight+2, w-2, LOWERED); + + form = new_form(cfield); + set_form_win(form, formwin); + /* should be formheight */ + set_form_sub(form, derwin(formwin, nitems, w-4, 1, 1)); + post_form(form); -int -bsddialog_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int argc, char **argv) -{ - int i, output, nitems; - struct formitem items[128]; - - if ((argc % 9) != 0) - return (-1); - - nitems = argc / 9; - for (i=0; i<nitems; i++) { - items[i].label = argv[9*i]; - items[i].ylabel = atoi(argv[9*i+1]); - items[i].xlabel = atoi(argv[9*i+2]); - items[i].item = argv[9*i+3]; - items[i].yitem = atoi(argv[9*i+4]); - items[i].xitem = atoi(argv[9*i+5]); - items[i].itemlen = atoi(argv[9*i+6]); - items[i].inputlen = atoi(argv[9*i+7]); - items[i].itemflags = atoi(argv[9*i+8]); - } + for (i=0; i < (int)nitems; i++) + mvwaddstr(formwin, items[i].ylabel, items[i].xlabel, items[i].label); - output = do_mixedform(conf, text, rows, cols, formheight, nitems, items); + wrefresh(formwin); - return output; -} + do { + output = form_handler(conf, widget, h-2, w, bs, formwin, form, + cfield, nitems, items); -int -bsddialog_form(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int argc, char **argv) -{ - int i, output, nitems, itemlen, inputlen; - unsigned int flags = 0; - struct formitem items[128]; - - if ((argc % 8) != 0) - return (-1); - - nitems = argc / 8; - for (i=0; i<nitems; i++) { - items[i].label = argv[8*i]; - items[i].ylabel = atoi(argv[8*i+1]); - items[i].xlabel = atoi(argv[8*i+2]); - items[i].item = argv[8*i+3]; - items[i].yitem = atoi(argv[8*i+4]); - items[i].xitem = atoi(argv[8*i+5]); - - itemlen = atoi(argv[8*i+6]); - items[i].itemlen = abs(itemlen); - - inputlen = atoi(argv[8*i+7]); - items[i].inputlen = inputlen == 0 ? abs(itemlen) : inputlen; - - flags = flags | (itemlen < 0 ? ITEMREADONLY : 0); - items[i].itemflags = flags; - } + if(update_widget_withtextpad(conf, shadow, widget, h, w, + RAISED, textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); - output = do_mixedform(conf, text, rows, cols, formheight, nitems, items); + prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, + y + h - formheight, x + 1 + w - t.text.hmargin); - return output; -} + draw_borders(conf, formwin, formheight+2, w-2, LOWERED); + /* wrefresh(formwin); */ + } while (output == REDRAWFORM); -int -bsddialog_passwordform(struct bsddialog_conf conf, char* text, int rows, int cols, - int formheight, int argc, char **argv) -{ - int i, output, nitems, itemlen, inputlen; - unsigned int flags = ITEMHIDDEN; - struct formitem items[128]; - - if ((argc % 8) != 0) - return (-1); - - nitems = argc / 8; - for (i=0; i<nitems; i++) { - items[i].label = argv[8*i]; - items[i].ylabel = atoi(argv[8*i+1]); - items[i].xlabel = atoi(argv[8*i+2]); - items[i].item = argv[8*i+3]; - items[i].yitem = atoi(argv[8*i+4]); - items[i].xitem = atoi(argv[8*i+5]); - - itemlen = atoi(argv[8*i+6]); - items[i].itemlen = abs(itemlen); - - inputlen = atoi(argv[8*i+7]); - items[i].inputlen = inputlen == 0 ? abs(itemlen) : inputlen; - - flags = flags | (itemlen < 0 ? ITEMREADONLY : 0); - items[i].itemflags = flags; + unpost_form(form); + free_form(form); + for (i=0; i < (int)nitems; i++) { + free_field(cfield[i]); + free(myfields[i].buf); } + free(cfield); + free(myfields); - output = do_mixedform(conf, text, rows, cols, formheight, nitems, items); + delwin(formwin); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } - diff --git a/lib/infobox.c b/lib/infobox.c index 0d3eca86a258..304e68a62107 100644 --- a/lib/infobox.c +++ b/lib/infobox.c @@ -44,7 +44,7 @@ extern struct bsddialog_theme t; static int -infobox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, +infobox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, char *text) { int maxword, maxline, nlines; @@ -54,7 +54,7 @@ infobox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, if (cols == BSDDIALOG_AUTOSIZE) { /* text size */ - *w = maxline + VBORDERS + t.texthmargin * 2; + *w = maxline + VBORDERS + t.text.hmargin * 2; /* avoid terminal overflow */ *w = MIN(*w, widget_max_width(conf)); } @@ -74,7 +74,7 @@ infobox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, static int infobox_checksize(int rows, int cols) { - if (cols < HBORDERS + 1 + (int) t.texthmargin * 2) + if (cols < HBORDERS + 1 + (int) t.text.hmargin * 2) RETURN_ERROR("Few cols, infobox needs at least width 3 + text "\ "margins"); @@ -85,7 +85,7 @@ static int infobox_checksize(int rows, int cols) } int -bsddialog_infobox(struct bsddialog_conf conf, char* text, int rows, int cols) +bsddialog_infobox(struct bsddialog_conf *conf, char* text, int rows, int cols) { WINDOW *shadow, *widget, *textpad; int y, x, h, w, htextpad; @@ -103,7 +103,7 @@ bsddialog_infobox(struct bsddialog_conf conf, char* text, int rows, int cols) &textpad, &htextpad, text, false) != 0) return BSDDIALOG_ERROR; - pnoutrefresh(textpad, 0, 0, y+1, x+1+t.texthmargin, y+h-2, x+w-t.texthmargin); + pnoutrefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-2, x+w-t.text.hmargin); doupdate(); diff --git a/lib/lib_util.c b/lib/lib_util.c index a1cdac1169c4..0751a666de92 100644 --- a/lib/lib_util.c +++ b/lib/lib_util.c @@ -65,9 +65,9 @@ int hide_widget(int y, int x, int h, int w, bool withshadow) WINDOW *clear; /* no check: y, x, h and w are checked by the builders */ - if ((clear = newwin(h, w, y + t.shadowrows, x + t.shadowcols)) == NULL) + if ((clear = newwin(h, w, y + t.shadow.h, x + t.shadow.w)) == NULL) RETURN_ERROR("Cannot hide the widget"); - wbkgd(clear, t.backgroundcolor); + wbkgd(clear, t.terminal.color); if (withshadow) wrefresh(clear); @@ -81,23 +81,23 @@ int hide_widget(int y, int x, int h, int w, bool withshadow) } /* F1 help */ -int f1help(struct bsddialog_conf conf) +int f1help(struct bsddialog_conf *conf) { - char *file = conf.hfile; - char *title = conf.title; + char *file = conf->hfile; + char *title = conf->title; int output; - conf.hfile = NULL; - conf.clear = true; - conf.y = BSDDIALOG_CENTER; - conf.x = BSDDIALOG_CENTER; - conf.title = "HELP"; - conf.sleep = 0; + conf->hfile = NULL; + conf->clear = true; + conf->y = BSDDIALOG_CENTER; + conf->x = BSDDIALOG_CENTER; + conf->title = "HELP"; + conf->sleep = 0; output = bsddialog_textbox(conf, file, BSDDIALOG_AUTOSIZE, BSDDIALOG_AUTOSIZE); - conf.hfile = file; - conf.title = title; + conf->hfile = file; + conf->title = title; return output; } @@ -110,24 +110,24 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected, int i, color_arrows, color_shortkey, color_button; if (selected) { - color_arrows = t.currbuttdelimcolor; - color_shortkey = t.currshortkeycolor; - color_button = t.currbuttoncolor; + color_arrows = t.button.f_delimcolor; + color_shortkey = t.button.f_shortcutcolor; + color_button = t.button.f_color; } else { - color_arrows = t.buttdelimcolor; - color_shortkey = t.shortkeycolor; - color_button = t.buttoncolor; + color_arrows = t.button.delimcolor; + color_shortkey = t.button.shortcutcolor; + color_button = t.button.color; } wattron(window, color_arrows); - mvwaddch(window, y, x, t.buttleftch); + mvwaddch(window, y, x, t.button.leftch); wattroff(window, color_arrows); wattron(window, color_button); for(i = 1; i < size - 1; i++) waddch(window, ' '); wattroff(window, color_button); wattron(window, color_arrows); - mvwaddch(window, y, x + i, t.buttrightchar); + mvwaddch(window, y, x + i, t.button.rightch); wattroff(window, color_arrows); x = x + 1 + ((size - 2 - strlen(text))/2); @@ -147,18 +147,18 @@ draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey) { int i, x, start_x; - start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.buttonspace; + start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.button.space; start_x = cols/2 - start_x/2; for (i = 0; i < (int) bs.nbuttons; i++) { - x = i * (bs.sizebutton + t.buttonspace); + x = i * (bs.sizebutton + t.button.space); draw_button(window, y, start_x + x, bs.sizebutton, bs.label[i], i == bs.curr, shortkey); } } void -get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel, +get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel, char *extralabel, char *nocancellabel, char *helplabel) { int i; @@ -171,41 +171,53 @@ get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel, bs->curr = 0; bs->sizebutton = 0; - if (yesoklabel != NULL && conf.button.no_ok == false) { + if (yesoklabel != NULL && conf->button.no_ok == false) { bs->label[0] = yesoklabel; bs->value[0] = BSDDIALOG_YESOK; bs->nbuttons += 1; } - if (extralabel != NULL && conf.button.extra_button) { + if (extralabel != NULL && conf->button.extra_button) { bs->label[bs->nbuttons] = extralabel; bs->value[bs->nbuttons] = BSDDIALOG_EXTRA; bs->nbuttons += 1; } - if (nocancellabel != NULL && conf.button.no_cancel == false) { + if (nocancellabel != NULL && conf->button.no_cancel == false) { bs->label[bs->nbuttons] = nocancellabel; bs->value[bs->nbuttons] = BSDDIALOG_NOCANCEL; - if (conf.button.defaultno) + if (conf->button.defaultno) bs->curr = bs->nbuttons; bs->nbuttons += 1; } - if (helplabel != NULL && conf.button.help_button) { + if (helplabel != NULL && conf->button.help_button) { bs->label[bs->nbuttons] = helplabel; bs->value[bs->nbuttons] = BSDDIALOG_HELP; bs->nbuttons += 1; } + if (conf->button.generic1_label != NULL) { + bs->label[bs->nbuttons] = conf->button.generic1_label; + bs->value[bs->nbuttons] = BSDDIALOG_GENERIC1; + bs->nbuttons += 1; + } + + if (conf->button.generic2_label != NULL) { + bs->label[bs->nbuttons] = conf->button.generic2_label; + bs->value[bs->nbuttons] = BSDDIALOG_GENERIC2; + bs->nbuttons += 1; + } + if (bs->nbuttons == 0) { bs->label[0] = DEFAULT_BUTTON_LABEL; bs->value[0] = DEFAULT_BUTTON_VALUE; bs->nbuttons = 1; } - if (conf.button.default_label != NULL) { + if (conf->button.default_label != NULL) { for (i=0; i<(int)bs->nbuttons; i++) { - if (strcmp(conf.button.default_label, bs->label[i]) == 0) + if (strcmp(conf->button.default_label, bs->label[i]) == 0) bs->curr = i; } } @@ -217,39 +229,29 @@ get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel, } /* Text */ +static bool is_ncurses_attr(char *text) +{ -// old text, to delete in the future -enum token { TEXT, WS, END }; + if (strnlen(text, 3) < 3) + return false; + + if (text[0] != '\\' || text[1] != 'Z') + return false; + + return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true); +} static bool check_set_ncurses_attr(WINDOW *win, char *text) { - bool isattr; - int colors[8] = { - COLOR_BLACK, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW, - COLOR_BLUE, - COLOR_MAGENTA, - COLOR_CYAN, - COLOR_WHITE - }; - - if (text[0] == '\0' || text[0] != '\\') - return false; - if (text[1] == '\0' || text[1] != 'Z') - return false; - if (text[2] == '\0') + + if (is_ncurses_attr(text) == false) return false; - if ((text[2] - 48) >= 0 && (text[2] - 48) < 8) { - // tocheck: import BSD_COLOR - // tofix color background - wattron(win, COLOR_PAIR(colors[text[2] - 48] * 8 + COLOR_WHITE + 1)); + if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) { + wattron(win, bsddialog_color( text[2] - '0', COLOR_WHITE) ); return true; } - isattr = true; switch (text[2]) { case 'n': wattrset(win, A_NORMAL); @@ -272,143 +274,9 @@ static bool check_set_ncurses_attr(WINDOW *win, char *text) case 'U': wattroff(win, A_UNDERLINE); break; - default: - isattr = false; } - return isattr; -} - -static bool isws(int ch) -{ - - return (ch == ' ' || ch == '\t' || ch == '\n'); -} - -static int -next_token(char *text, char *valuestr) -{ - int i, j; - enum token tok; - - i = j = 0; - - if (text[0] == '\0') - return END; - - while (text[i] != '\0') { - if (isws(text[i])) { - if (i == 0) { - valuestr[0] = text[i]; - valuestr[1] = '\0'; - tok = WS; - } - break; - } - - valuestr[j] = text[i]; - j++; - valuestr[j] = '\0'; - i++; - tok = TEXT; - } - - return tok; -} - -static void -print_string(WINDOW *win, int *y, int *x, int minx, int maxx, char *str, bool color) -{ - int i, j, len, reallen; - - if(strlen(str) == 0) - return; - - len = reallen = strlen(str); - if (color) { - i=0; - while (i < len) { - if (check_set_ncurses_attr(win, str+i)) - reallen -= 3; - i++; - } - } - - i = 0; - while (i < len) { - if (*x + reallen > maxx) { - *y = (*x != minx ? *y+1 : *y); - *x = minx; - } - j = *x; - while (j < maxx && i < len) { - if (color && check_set_ncurses_attr(win, str+i)) { - i += 3; - } else { - mvwaddch(win, *y, j, str[i]); - i++; - reallen--; - j++; - *x = j; - } - } - } -} - -void -print_text(struct bsddialog_conf conf, WINDOW *pad, int starty, int minx, int maxx, - char *text) -{ - char *valuestr; - int x, y; - bool loop; - enum token tok; - - valuestr = malloc(strlen(text) + 1); - - x = minx; - y = starty; - loop = true; - while (loop) { - tok = next_token(text, valuestr); - switch (tok) { - case END: - loop = false; - break; - case WS: - text += strlen(valuestr); - print_string(pad, &y, &x, minx, maxx, valuestr, false /*useless*/); - break; - case TEXT: - text += strlen(valuestr); - print_string(pad, &y, &x, minx, maxx, valuestr, conf.text.colors); - break; - } - } - - free(valuestr); -} - -// new text funcs - -static bool is_ncurses_attr(char *text) -{ - bool isattr; - - if (strnlen(text, 3) < 3) - return false; - - if (text[0] != '\\' || text[1] != 'Z') - return false; - - if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) - return true; - - isattr = text[2] == 'n' || text[2] == 'b' || text[2] == 'B' || - text[2] == 'r' || text[2] == 'R' || text[2] == 'u' || - text[2] == 'U'; - - return isattr; + return true; } static void @@ -454,7 +322,7 @@ print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool colo } } -static void prepare_text(struct bsddialog_conf conf, char *text, char *buf) +static void prepare_text(struct bsddialog_conf *conf, char *text, char *buf) { int i, j; @@ -468,7 +336,7 @@ static void prepare_text(struct bsddialog_conf conf, char *text, char *buf) i++; break; case 'n': - if (conf.text.no_nl_expand) { + if (conf->text.no_nl_expand) { j++; buf[j] = 'n'; } else @@ -476,7 +344,7 @@ static void prepare_text(struct bsddialog_conf conf, char *text, char *buf) i++; break; case 't': - if (conf.text.no_collapse) { + if (conf->text.no_collapse) { j++; buf[j] = 't'; } else @@ -486,23 +354,23 @@ static void prepare_text(struct bsddialog_conf conf, char *text, char *buf) } break; case '\n': - buf[j] = conf.text.cr_wrap ? ' ' : '\n'; + buf[j] = conf->text.cr_wrap ? ' ' : '\n'; break; case '\t': - buf[j] = conf.text.no_collapse ? '\t' : ' '; + buf[j] = conf->text.no_collapse ? '\t' : ' '; break; default: buf[j] = text[i]; } i++; - j += (buf[j] == ' ' && conf.text.trim && j > 0 && buf[j-1] == ' ') ? + j += (buf[j] == ' ' && conf->text.trim && j > 0 && buf[j-1] == ' ') ? 0 : 1; } buf[j] = '\0'; } int -get_text_properties(struct bsddialog_conf conf, char *text, int *maxword, +get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword, int *maxline, int *nlines) { char *buf; @@ -524,7 +392,7 @@ get_text_properties(struct bsddialog_conf conf, char *text, int *maxword, wordlen = 0; continue; } - if (conf.text.colors && is_ncurses_attr(buf + i)) + if (conf->text.colors && is_ncurses_attr(buf + i)) i += 3; else wordlen++; @@ -541,7 +409,7 @@ get_text_properties(struct bsddialog_conf conf, char *text, int *maxword, linelen = 0; break; default: - if (conf.text.colors && is_ncurses_attr(buf + i)) + if (conf->text.colors && is_ncurses_attr(buf + i)) i += 3; else linelen++; @@ -555,8 +423,9 @@ get_text_properties(struct bsddialog_conf conf, char *text, int *maxword, return 0; } -static int -print_textpad(struct bsddialog_conf conf, WINDOW *pad, int *rows, int cols, char *text) +int +print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols, + char *text) { char *buf, *string; int i, j, x, y; @@ -580,7 +449,7 @@ print_textpad(struct bsddialog_conf conf, WINDOW *pad, int *rows, int cols, char string[j] == '\t' || string[j] == ' ') { if (j != 0) { string[j] = '\0'; - print_str(pad, rows, &y, &x, cols, string, conf.text.colors); + print_str(pad, rows, &y, &x, cols, string, conf->text.colors); } } @@ -633,15 +502,15 @@ print_textpad(struct bsddialog_conf conf, WINDOW *pad, int *rows, int cols, char * max y, that is from 0 to LINES - 1 - t.shadowrows, * could not be max height but avoids problems with checksize */ -int widget_max_height(struct bsddialog_conf conf) +int widget_max_height(struct bsddialog_conf *conf) { int maxheight; - if ((maxheight = conf.shadow ? LINES - 1 - t.shadowrows : LINES - 1) <= 0) + if ((maxheight = conf->shadow ? LINES - 1 - t.shadow.h : LINES - 1) <= 0) RETURN_ERROR("Terminal too small, LINES - shadow <= 0"); - if (conf.y > 0) - if ((maxheight -= conf.y) <=0) + if (conf->y > 0) + if ((maxheight -= conf->y) <=0) RETURN_ERROR("Terminal too small, LINES - shadow - y <= 0"); return maxheight; @@ -651,21 +520,21 @@ int widget_max_height(struct bsddialog_conf conf) * max x, that is from 0 to COLS - 1 - t.shadowcols, * * could not be max height but avoids problems with checksize */ -int widget_max_width(struct bsddialog_conf conf) +int widget_max_width(struct bsddialog_conf *conf) { int maxwidth; - if ((maxwidth = conf.shadow ? COLS - 1 - t.shadowcols : COLS - 1) <= 0) + if ((maxwidth = conf->shadow ? COLS - 1 - t.shadow.w : COLS - 1) <= 0) RETURN_ERROR("Terminal too small, COLS - shadow <= 0"); - if (conf.x > 0) - if ((maxwidth -= conf.x) <=0) + if (conf->x > 0) + if ((maxwidth -= conf->x) <=0) RETURN_ERROR("Terminal too small, COLS - shadow - x <= 0"); return maxwidth; } int -set_widget_size(struct bsddialog_conf conf, int rows, int cols, int *h, int *w) +set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w) { int maxheight, maxwidth; @@ -700,33 +569,33 @@ set_widget_size(struct bsddialog_conf conf, int rows, int cols, int *h, int *w) } int -set_widget_position(struct bsddialog_conf conf, int *y, int *x, int h, int w) +set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w) { - if (conf.y == BSDDIALOG_CENTER) + if (conf->y == BSDDIALOG_CENTER) *y = LINES/2 - h/2; - else if (conf.y < BSDDIALOG_CENTER) + else if (conf->y < BSDDIALOG_CENTER) RETURN_ERROR("Negative begin y (less than -1)"); - else if (conf.y >= LINES) + else if (conf->y >= LINES) RETURN_ERROR("Begin Y under the terminal"); else - *y = conf.y; + *y = conf->y; - if ((*y + h + (conf.shadow ? (int) t.shadowrows : 0)) > LINES) + if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > LINES) RETURN_ERROR("The lower of the box under the terminal "\ "(begin Y + height (+ shadow) > terminal lines)"); - if (conf.x == BSDDIALOG_CENTER) + if (conf->x == BSDDIALOG_CENTER) *x = COLS/2 - w/2; - else if (conf.x < BSDDIALOG_CENTER) + else if (conf->x < BSDDIALOG_CENTER) RETURN_ERROR("Negative begin x (less than -1)"); - else if (conf.x >= COLS) + else if (conf->x >= COLS) RETURN_ERROR("Begin X over the right of the terminal"); else - *x = conf.x; + *x = conf->x; - if ((*x + w + (conf.shadow ? (int) t.shadowcols : 0)) > COLS) + if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > COLS) RETURN_ERROR("The right of the box over the terminal "\ "(begin X + width (+ shadow) > terminal cols)"); @@ -735,7 +604,7 @@ set_widget_position(struct bsddialog_conf conf, int *y, int *x, int h, int w) /* Widgets builders */ void -draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols, +draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols, enum elevation elev) { int leftcolor, rightcolor; @@ -751,14 +620,14 @@ draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols, ltee = ACS_LTEE; rtee = ACS_RTEE; - if (conf.no_lines == false) { - if (conf.ascii_lines) { + if (conf->no_lines == false) { + if (conf->ascii_lines) { ls = rs = '|'; ts = bs = '-'; tl = tr = bl = br = ltee = rtee = '+'; } - leftcolor = elev == RAISED ? t.lineraisecolor : t.linelowercolor; - rightcolor = elev == RAISED ? t.linelowercolor : t.lineraisecolor; + leftcolor = elev == RAISED ? t.widget.lineraisecolor : t.widget.linelowercolor; + rightcolor = elev == RAISED ? t.widget.linelowercolor : t.widget.lineraisecolor; wattron(win, leftcolor); wborder(win, ls, rs, ts, bs, tl, tr, bl, br); wattroff(win, leftcolor); @@ -773,7 +642,7 @@ draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols, } WINDOW * -new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols, +new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols, enum elevation elev) { WINDOW *win; @@ -783,7 +652,7 @@ new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols, return NULL; } - wbkgd(win, t.widgetcolor); + wbkgd(win, t.widget.color); draw_borders(conf, win, rows, cols, elev); @@ -795,17 +664,17 @@ new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols, * to check at the end. */ static int -draw_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, +draw_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, int h, int w, enum elevation elev, WINDOW *textpad, int *htextpad, char *text, bool buttons) { int ts, ltee, rtee; int colorsurroundtitle; - ts = conf.ascii_lines ? '-' : ACS_HLINE; - ltee = conf.ascii_lines ? '+' : ACS_LTEE; - rtee = conf.ascii_lines ? '+' : ACS_RTEE; - colorsurroundtitle = elev == RAISED ? t.lineraisecolor : t.linelowercolor; + ts = conf->ascii_lines ? '-' : ACS_HLINE; + ltee = conf->ascii_lines ? '+' : ACS_LTEE; + rtee = conf->ascii_lines ? '+' : ACS_RTEE; + colorsurroundtitle = elev == RAISED ? t.widget.lineraisecolor : t.widget.linelowercolor; if (shadow != NULL) wnoutrefresh(shadow); @@ -813,43 +682,43 @@ draw_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, // move / resize now or the caller? draw_borders(conf, widget, h, w, elev); - if (conf.title != NULL) { - if (t.surroundtitle && conf.no_lines == false) { + if (conf->title != NULL) { + if (t.widget.delimtitle && conf->no_lines == false) { wattron(widget, colorsurroundtitle); - mvwaddch(widget, 0, w/2 - strlen(conf.title)/2 - 1, rtee); + mvwaddch(widget, 0, w/2 - strlen(conf->title)/2 - 1, rtee); wattroff(widget, colorsurroundtitle); } - wattron(widget, t.titlecolor); - mvwaddstr(widget, 0, w/2 - strlen(conf.title)/2, conf.title); - wattroff(widget, t.titlecolor); - if (t.surroundtitle && conf.no_lines == false) { + wattron(widget, t.widget.titlecolor); + mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title); + wattroff(widget, t.widget.titlecolor); + if (t.widget.delimtitle && conf->no_lines == false) { wattron(widget, colorsurroundtitle); waddch(widget, ltee); wattroff(widget, colorsurroundtitle); } } - if (conf.hline != NULL) { - wattron(widget, t.bottomtitlecolor); - wmove(widget, h - 1, w/2 - strlen(conf.hline)/2 - 1); + if (conf->hline != NULL) { + wattron(widget, t.widget.bottomtitlecolor); + wmove(widget, h - 1, w/2 - strlen(conf->hline)/2 - 1); waddch(widget, '['); - waddstr(widget, conf.hline); + waddstr(widget, conf->hline); waddch(widget, ']'); - wattroff(widget, t.bottomtitlecolor); + wattroff(widget, t.widget.bottomtitlecolor); } - if (textpad == NULL && text != NULL) /* no pad, text null for textbox */ - print_text(conf, widget, 1, 2, w-3, text); + //if (textpad == NULL && text != NULL) /* no pad, text null for textbox */ + // print_text(conf, widget, 1, 2, w-3, text); - if (buttons && conf.no_lines == false) { - wattron(widget, t.lineraisecolor); + if (buttons && conf->no_lines == false) { + wattron(widget, t.widget.lineraisecolor); mvwaddch(widget, h-3, 0, ltee); mvwhline(widget, h-3, 1, ts, w-2); - wattroff(widget, t.lineraisecolor); + wattroff(widget, t.widget.lineraisecolor); - wattron(widget, t.linelowercolor); + wattron(widget, t.widget.linelowercolor); mvwaddch(widget, h-3, w-1, rtee); - wattroff(widget, t.linelowercolor); + wattroff(widget, t.widget.linelowercolor); } wnoutrefresh(widget); @@ -859,7 +728,7 @@ draw_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, if (text != NULL) /* programbox etc */ if (print_textpad(conf, textpad, htextpad, - w - HBORDERS - t.texthmargin * 2, text) !=0) + w - HBORDERS - t.text.hmargin * 2, text) !=0) return BSDDIALOG_ERROR; return 0; @@ -870,7 +739,7 @@ draw_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, * to check at the end. */ int -update_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, +update_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, int h, int w, enum elevation elev, WINDOW *textpad, int *htextpad, char *text, bool buttons) { @@ -889,21 +758,21 @@ update_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, * to check at the end. */ int -new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow, +new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y, int x, int h, int w, enum elevation elev, WINDOW **textpad, int *htextpad, char *text, bool buttons) { int error; - if (conf.shadow) { - *shadow = newwin(h, w, y + t.shadowrows, x + t.shadowcols); + if (conf->shadow) { + *shadow = newwin(h, w, y + t.shadow.h, x + t.shadow.w); if (*shadow == NULL) RETURN_ERROR("Cannot build shadow"); - wbkgd(*shadow, t.shadowcolor); + wbkgd(*shadow, t.shadow.color); } if ((*widget = new_boxed_window(conf, y, x, h, w, elev)) == NULL) { - if (conf.shadow) + if (conf->shadow) delwin(*shadow); return BSDDIALOG_ERROR; } @@ -916,14 +785,14 @@ new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow, if (text != NULL) { /* programbox etc */ *htextpad = 1; - *textpad = newpad(*htextpad, w - HBORDERS - t.texthmargin * 2); + *textpad = newpad(*htextpad, w - HBORDERS - t.text.hmargin * 2); if (*textpad == NULL) { delwin(*textpad); - if (conf.shadow) + if (conf->shadow) delwin(*shadow); RETURN_ERROR("Cannot build the pad window for text"); } - wbkgd(*textpad, t.widgetcolor); + wbkgd(*textpad, t.widget.color); } error = draw_widget_withtextpad(conf, *shadow, *widget, h, w, elev, @@ -932,65 +801,30 @@ new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow, return error; } -int -new_widget(struct bsddialog_conf conf, WINDOW **widget, int *y, int *x, - char *text, int *h, int *w, WINDOW **shadow, bool buttons) -{ - - // to delete (each widget has to check its x,y,h,w) - if (*h <= 0) - ; /* todo */ - - if (*w <= 0) - ; /* todo */ - - *y = (conf.y < 0) ? (LINES/2 - *h/2) : conf.y; - *x = (conf.x < 0) ? (COLS/2 - *w/2) : conf.x; - - if (new_widget_withtextpad(conf, shadow, widget, *y, *x, *h, *w, RAISED, - NULL, NULL, text, buttons) != 0) - return BSDDIALOG_ERROR; - - if (conf.shadow) - wrefresh(*shadow); - - wrefresh(*widget); - - return 0; -} - void -end_widget_withtextpad(struct bsddialog_conf conf, WINDOW *window, int h, int w, +end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w, WINDOW *textpad, WINDOW *shadow) { int y, x; getbegyx(window, y, x); /* for clear, add y & x to args? */ - if (conf.sleep > 0) - sleep(conf.sleep); + if (conf->sleep > 0) + sleep(conf->sleep); if (textpad != NULL) delwin(textpad); delwin(window); - if (conf.shadow) + if (conf->shadow) delwin(shadow); - if (conf.clear) + if (conf->clear) hide_widget(y, x, h, w, shadow != NULL); - if (conf.get_height != NULL) - *conf.get_height = h; - if (conf.get_width != NULL) - *conf.get_width = w; -} - -void -end_widget(struct bsddialog_conf conf, WINDOW *window, int h, int w, - WINDOW *shadow) -{ - - end_widget_withtextpad(conf, window, h, w, NULL, shadow); + if (conf->get_height != NULL) + *conf->get_height = h; + if (conf->get_width != NULL) + *conf->get_width = w; } diff --git a/lib/lib_util.h b/lib/lib_util.h index b6fe1dd86b59..b3598e900e9e 100644 --- a/lib/lib_util.h +++ b/lib/lib_util.h @@ -29,7 +29,7 @@ #define _LIBBSDDIALOG_UTIL_H_ /* - * Utils to implement widgets - Internal library API + * Utils to implement widgets - Internal library API - Dafult values */ #define HBORDERS 2 @@ -39,7 +39,7 @@ #define KEY_CTRL(x) ((x) & 0x1f) /* Set default aspect ratio to 9 */ -#define GET_ASPECT_RATIO(conf) (conf.aspect_ratio > 0 ? conf.aspect_ratio : 9) +#define GET_ASPECT_RATIO(conf) (conf->aspect_ratio > 0 ? conf->aspect_ratio : 9) /* debug */ #define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \ @@ -64,9 +64,9 @@ void set_error_string(char *string); #define LABEL_no_label "No" #define LABEL_ok_label "OK" #define LABEL_yes_label "Yes" -#define BUTTONLABEL(l) (conf.button.l != NULL ? conf.button.l : LABEL_ ##l) +#define BUTTONLABEL(l) (conf->button.l != NULL ? conf->button.l : LABEL_ ##l) -#define MAXBUTTONS 4 /* yes|ok - extra - no|cancel - help */ +#define MAXBUTTONS 6 /* yes|ok + extra + no|cancel + help + 2 generics */ struct buttons { unsigned int nbuttons; char *label[MAXBUTTONS]; @@ -76,7 +76,7 @@ struct buttons { }; void -get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel, +get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel, char *extralabel, char *nocancellabel, char *helplabel); void @@ -87,60 +87,52 @@ void draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey); /* help window with F1 key */ -int f1help(struct bsddialog_conf conf); +int f1help(struct bsddialog_conf *conf); /* cleaner */ int hide_widget(int y, int x, int h, int w, bool withshadow); /* (auto) size and (auto) position */ int -get_text_properties(struct bsddialog_conf conf, char *text, int *maxword, +get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword, int *maxline, int *nlines); -int widget_max_height(struct bsddialog_conf conf); -int widget_max_width(struct bsddialog_conf conf); +int widget_max_height(struct bsddialog_conf *conf); +int widget_max_width(struct bsddialog_conf *conf); int -set_widget_size(struct bsddialog_conf conf, int rows, int cols, int *h, int *w); +set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w); int -set_widget_position(struct bsddialog_conf conf, int *y, int *x, int h, int w); +set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w); /* widget builders */ -void -print_text(struct bsddialog_conf conf, WINDOW *pad, int starty, int minx, - int maxx, char *text); +int +print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols, + char *text); enum elevation { RAISED, LOWERED }; void -draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols, +draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols, enum elevation elev); WINDOW * -new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols, +new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols, enum elevation elev); int -new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow, +new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y, int x, int h, int w, enum elevation elev, WINDOW **textpad, int *htextpad, char *text, bool buttons); int -update_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow, +update_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, int h, int w, enum elevation elev, WINDOW *textpad, int *htextpad, char *text, bool buttons); void -end_widget_withtextpad(struct bsddialog_conf conf, WINDOW *window, int h, int w, +end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w, WINDOW *textpad, WINDOW *shadow); -int -new_widget(struct bsddialog_conf conf, WINDOW **widget, int *y, int *x, - char *text, int *h, int *w, WINDOW **shadow, bool buttons); - -void -end_widget(struct bsddialog_conf conf, WINDOW *window, int h, int w, - WINDOW *shadow); - #endif diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c index a5866f39bea9..bcc811a02e45 100644 --- a/lib/libbsddialog.c +++ b/lib/libbsddialog.c @@ -46,14 +46,11 @@ * Widgets implementation: * infobox.c infobox * messgebox.c msgbox - yesno - * menubox.c buildlist - checklist - menu - mixedlist - radiolist - treeview + * menubox.c buildlist - checklist - menu - mixedlist - radiolist * formbox.c inputbox - passwordbox - form - passwordform - mixedform - * editorbox.c editbox * barbox.c gauge - mixedgauge - rangebox - pause + * textbox.c textbox * timebox.c timebox - calendar - * commandbox.c prgbox - programbox - progressbox - * tailbox.c tailbox - tailboxbg - textbox - * filebox.c dselect - fselect */ extern struct bsddialog_theme t; @@ -103,12 +100,12 @@ int bsddialog_end(void) return 0; } -int bsddialog_backtitle(struct bsddialog_conf conf, char *backtitle) +int bsddialog_backtitle(struct bsddialog_conf *conf, char *backtitle) { mvaddstr(0, 1, backtitle); - if (conf.no_lines != true) - mvhline(1, 1, conf.ascii_lines ? '-' : ACS_HLINE, COLS-2); + if (conf->no_lines != true) + mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE, COLS-2); refresh(); diff --git a/lib/menubox.c b/lib/menubox.c index 523e41fdeb1b..72038d4b0246 100644 --- a/lib/menubox.c +++ b/lib/menubox.c @@ -40,7 +40,7 @@ #include "lib_util.h" #include "bsddialog_theme.h" -/* "Menu": checklist - menu - mixedlist - radiolist - treeview - buildlist */ +/* "Menu": checklist - menu - mixedlist - radiolist - buildlist */ #define DEPTHSPACE 4 #define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */ @@ -123,7 +123,7 @@ getfirst(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group, } static void -getfirst_with_default(struct bsddialog_conf conf, int ngroups, +getfirst_with_default(struct bsddialog_conf *conf, int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group, int *rel) { int i, j, a; @@ -142,8 +142,8 @@ getfirst_with_default(struct bsddialog_conf conf, int ngroups, } for (j = 0; j < (int) groups[i].nitems; j++) { item = &groups[i].items[j]; - if (conf.menu.default_item != NULL && item->name != NULL) { - if (strcmp(item->name, conf.menu.default_item) == 0) { + if (conf->menu.default_item != NULL && item->name != NULL) { + if (strcmp(item->name, conf->menu.default_item) == 0) { *abs = a; *group = i; *rel = j; @@ -288,31 +288,31 @@ getmode(enum menumode mode, struct bsddialog_menugroup group) } static void -drawitem(struct bsddialog_conf conf, WINDOW *pad, int y, +drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y, struct bsddialog_menuitem item, enum menumode mode, struct lineposition pos, bool curr) { int color, colorname, linech; - color = curr ? t.curritemcolor : t.itemcolor; - colorname = curr ? t.currtagcolor : t.tagcolor; + color = curr ? t.menu.f_desccolor : t.menu.desccolor; + colorname = curr ? t.menu.f_namecolor : t.menu.namecolor; if (mode == SEPARATORMODE) { - if (conf.no_lines == false) { - wattron(pad, t.itemcolor); - linech = conf.ascii_lines ? '-' : ACS_HLINE; + if (conf->no_lines == false) { + wattron(pad, t.menu.desccolor); + linech = conf->ascii_lines ? '-' : ACS_HLINE; mvwhline(pad, y, 0, linech, pos.line); - wattroff(pad, t.itemcolor); + wattroff(pad, t.menu.desccolor); } wmove(pad, y, pos.line/2 - (strlen(item.name)+strlen(item.desc))/2); - wattron(pad, t.namesepcolor); + wattron(pad, t.menu.namesepcolor); waddstr(pad, item.name); - wattroff(pad, t.namesepcolor); + wattroff(pad, t.menu.namesepcolor); if (strlen(item.name) > 0 && strlen(item.desc) > 0) waddch(pad, ' '); - wattron(pad, t.descsepcolor); + wattron(pad, t.menu.descsepcolor); waddstr(pad, item.desc); - wattroff(pad, t.descsepcolor); + wattroff(pad, t.menu.descsepcolor); return; } @@ -330,18 +330,18 @@ drawitem(struct bsddialog_conf conf, WINDOW *pad, int y, wattroff(pad, color); /* name */ - if (mode != BUILDLISTMODE && conf.menu.no_tags == false) { + if (mode != BUILDLISTMODE && conf->menu.no_name == false) { wattron(pad, colorname); mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.name); wattroff(pad, colorname); } /* description */ - if (conf.menu.no_items == false) { - if ((mode == BUILDLISTMODE || conf.menu.no_tags) && curr == false) - color = item.on ? t.tagcolor : t.itemcolor; + if (conf->menu.no_desc == false) { + if ((mode == BUILDLISTMODE || conf->menu.no_name) && curr == false) + color = item.on ? t.menu.namecolor : t.menu.desccolor; wattron(pad, color); - if (conf.menu.no_tags) + if (conf->menu.no_name) mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.desc); else mvwaddstr(pad, y, pos.xdesc, item.desc); @@ -359,7 +359,7 @@ drawitem(struct bsddialog_conf conf, WINDOW *pad, int y, } static void -menu_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, +menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, char *text, int linelen, unsigned int *menurows, int nitems, struct buttons bs) { @@ -371,7 +371,7 @@ menu_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, *w = VBORDERS; /* buttons size */ *w += bs.nbuttons * bs.sizebutton; - *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0; + *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; /* line size */ *w = MAX(*w, linelen + 6); /* @@ -413,7 +413,7 @@ menu_checksize(int rows, int cols, char *text, int menurows, int nitems, mincols = VBORDERS; /* buttons */ mincols += bs.nbuttons * bs.sizebutton; - mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0; + mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; /* line, comment to permet some cols hidden */ /* mincols = MAX(mincols, linelen); */ @@ -436,23 +436,22 @@ menu_checksize(int rows, int cols, char *text, int menurows, int nitems, /* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */ static void -update_menuwin(struct bsddialog_conf conf, WINDOW *menuwin, int h, int w, +update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w, int totnitems, unsigned int menurows, int ymenupad) { if (totnitems > (int) menurows) { draw_borders(conf, menuwin, h, w, LOWERED); - if (ymenupad > 0) { - wattron(menuwin, t.lineraisecolor); - mvwprintw(menuwin, 0, 2, "^^"); - wattroff(menuwin, t.lineraisecolor); - } - if ((int) (ymenupad + menurows) < totnitems) { - wattron(menuwin, t.linelowercolor); - mvwprintw(menuwin, h-1, 2, "vv"); - wattroff(menuwin, t.linelowercolor); - } + wattron(menuwin, t.menu.arrowcolor); + + if (ymenupad > 0) + mvwprintw(menuwin, 0, 2, "^^^"); + + if ((int) (ymenupad + menurows) < totnitems) + mvwprintw(menuwin, h-1, 2, "vvv"); + + wattroff(menuwin, t.menu.arrowcolor); mvwprintw(menuwin, h-1, w-10, "%3d%%", 100 * (ymenupad + menurows) / totnitems); @@ -460,7 +459,7 @@ update_menuwin(struct bsddialog_conf conf, WINDOW *menuwin, int h, int w, } static int -do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, +do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, enum menumode mode, int ngroups, struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) { @@ -503,8 +502,8 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc)); } } - pos.maxname = conf.menu.no_tags ? 0 : pos.maxname; - pos.maxdesc = conf.menu.no_items ? 0 : pos.maxdesc; + pos.maxname = conf->menu.no_name ? 0 : pos.maxname; + pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc; pos.maxdepth *= DEPTHSPACE; pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0); @@ -530,14 +529,14 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, &textpad, &htextpad, text, true) != 0) return BSDDIALOG_ERROR; - prefresh(textpad, 0, 0, y + 1, x + 1 + t.texthmargin, - y + h - menurows, x + 1 + w - t.texthmargin); + prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, + y + h - menurows, x + 1 + w - t.text.hmargin); menuwin = new_boxed_window(conf, y + h - 5 - menurows, x + 2, menurows+2, w-4, LOWERED); menupad = newpad(totnitems, pos.line); - wbkgd(menupad, t.widgetcolor); + wbkgd(menupad, t.widget.color); getfirst_with_default(conf, ngroups, groups, &abs, &g, &rel); ymenupad = 0; @@ -553,7 +552,7 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, ys = y + h - 5 - menurows + 1; ye = y + h - 5 ; - if (conf.menu.align_left || (int)pos.line > w - 6) { + if (conf->menu.align_left || (int)pos.line > w - 6) { xs = x + 3; xe = xs + w - 7; } @@ -608,15 +607,15 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, wrefresh(widget); } break; - case KEY_CTRL('E'): /* add conf.menu.extrahelpkey ? */ + case KEY_CTRL('E'): /* add conf->menu.extrahelpkey ? */ case KEY_F(1): - if (conf.hfile == NULL) + if (conf->hfile == NULL) break; if (f1help(conf) != 0) return BSDDIALOG_ERROR; /* No break! the terminal size can change */ case KEY_RESIZE: - hide_widget(y, x, h, w,conf.shadow); + hide_widget(y, x, h, w,conf->shadow); /* * Unnecessary, but, when the columns decrease the @@ -635,7 +634,7 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, return BSDDIALOG_ERROR; wclear(shadow); - mvwin(shadow, y + t.shadowrows, x + t.shadowcols); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); wresize(shadow, h, w); wclear(widget); @@ -644,7 +643,7 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, htextpad = 1; wclear(textpad); - wresize(textpad, 1, w - HBORDERS - t.texthmargin * 2); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); if(update_widget_withtextpad(conf, shadow, widget, h, w, RAISED, textpad, &htextpad, text, true) != 0) @@ -653,8 +652,8 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, draw_buttons(widget, h-2, w, bs, true); wrefresh(widget); - prefresh(textpad, 0, 0, y + 1, x + 1 + t.texthmargin, - y + h - menurows, x + 1 + w - t.texthmargin); + prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, + y + h - menurows, x + 1 + w - t.text.hmargin); wclear(menuwin); mvwin(menuwin, y + h - 5 - menurows, x + 2); @@ -665,7 +664,7 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, ys = y + h - 5 - menurows + 1; ye = y + h - 5 ; - if (conf.menu.align_left || (int)pos.line > w - 6) { + if (conf->menu.align_left || (int)pos.line > w - 6) { xs = x + 3; xe = xs + w - 7; } @@ -687,7 +686,6 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, output = bs.value[i]; loop = false; } - } if (abs < 0) @@ -743,16 +741,14 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, else if (currmode == CHECKLISTMODE) item->on = !item->on; else { /* RADIOLISTMODE */ - if (item->on == true) - break; for (i=0; i < (int) groups[g].nitems; i++) - if (groups[g].items[i].on == true) { + if (groups[g].items[i].on == true && i != rel) { groups[g].items[i].on = false; drawitem(conf, menupad, abs - rel + i, groups[g].items[i], currmode, pos, false); } - item->on = true; + item->on = !item->on; } drawitem(conf, menupad, abs, *item, currmode, pos, true); prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); @@ -775,7 +771,7 @@ do_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, * API */ -int bsddialog_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols, +int bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) { @@ -788,7 +784,7 @@ int bsddialog_mixedlist(struct bsddialog_conf conf, char* text, int rows, int co } int -bsddialog_checklist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem) { @@ -803,7 +799,7 @@ bsddialog_checklist(struct bsddialog_conf conf, char* text, int rows, int cols, } int -bsddialog_menu(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem) { @@ -818,7 +814,7 @@ bsddialog_menu(struct bsddialog_conf conf, char* text, int rows, int cols, } int -bsddialog_radiolist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem) { @@ -832,31 +828,57 @@ bsddialog_radiolist(struct bsddialog_conf conf, char* text, int rows, int cols, return output; } -int -bsddialog_treeview(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int menurows, int nitems, struct bsddialog_menuitem *items, - int *focusitem) +/* todo */ +static int buildlist_autosize(int rows, int cols) { - int output; - struct bsddialog_menugroup group = { - BSDDIALOG_RADIOLIST /* unused */, nitems, items}; - conf.menu.no_tags = true; - conf.menu.align_left = true; + if (cols == BSDDIALOG_AUTOSIZE) + RETURN_ERROR("Unimplemented cols autosize for buildlist"); - output = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE, - 1, &group, NULL, focusitem); + if (rows == BSDDIALOG_AUTOSIZE) + RETURN_ERROR("Unimplemented rows autosize for buildlist"); - return output; + return 0; +} + +/* to improve */ +static int +buildlist_checksize(int rows, int cols, char *text, int menurows, int nitems, + struct buttons bs) +{ + int mincols, textrow, menusize; + + mincols = VBORDERS; + /* buttons */ + mincols += bs.nbuttons * bs.sizebutton; + mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; + /* line, comment to permet some cols hidden */ + /* mincols = MAX(mincols, linelen); */ + + if (cols < mincols) + RETURN_ERROR("Few cols, width < size buttons or "\ + "name+descripion of the items"); + + textrow = text != NULL && strlen(text) > 0 ? 1 : 0; + + if (nitems > 0 && menurows == 0) + RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\ + "too small"); + + menusize = nitems > 0 ? 3 : 0; + if (rows < 2 + 2 + menusize + textrow) + RETURN_ERROR("Few lines for this menus"); + + return 0; } int -bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, +bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, int *focusitem) { - WINDOW *widget, *leftwin, *leftpad, *rightwin, *rightpad, *shadow; - int output, i, x, y, input; + WINDOW *widget, *textpad, *leftwin, *leftpad, *rightwin, *rightpad, *shadow; + int output, i, x, y, h, w, htextpad, input; bool loop, buttupdate, padsupdate, startleft; int nlefts, nrights, leftwinx, rightwinx, winsy, padscols, curr; enum side {LEFT, RIGHT} currV; @@ -871,36 +893,48 @@ bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, startleft = true; } - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; + get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), + BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (buildlist_autosize(rows, cols) != 0) + return BSDDIALOG_ERROR; + if (buildlist_checksize(h, w, text, menurows, nitems, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; - winsy = y + rows - 5 - menurows; + prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, + y + h - menurows, x + 1 + w - t.text.hmargin); + + winsy = y + h - 5 - menurows; leftwinx = x+2; - leftwin = new_boxed_window(conf, winsy, leftwinx, menurows+2, (cols-5)/2, + leftwin = new_boxed_window(conf, winsy, leftwinx, menurows+2, (w-5)/2, LOWERED); - rightwinx = x + cols - 2 -(cols-5)/2; + rightwinx = x + w - 2 -(w-5)/2; rightwin = new_boxed_window(conf, winsy, rightwinx, menurows+2, - (cols-5)/2, LOWERED); + (w-5)/2, LOWERED); wrefresh(leftwin); wrefresh(rightwin); - padscols = (cols-5)/2 - 2; + padscols = (w-5)/2 - 2; leftpad = newpad(nitems, pos.line); rightpad = newpad(nitems, pos.line); - wbkgd(leftpad, t.widgetcolor); - wbkgd(rightpad, t.widgetcolor); - - get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), - BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); + wbkgd(leftpad, t.widget.color); + wbkgd(rightpad, t.widget.color); currH = 0; currV = startleft ? LEFT : RIGHT; loop = buttupdate = padsupdate = true; while(loop) { if (buttupdate) { - draw_buttons(widget, rows-2, cols, bs, true); + draw_buttons(widget, h-2, w, bs, true); wrefresh(widget); buttupdate = false; } @@ -934,15 +968,16 @@ bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, input = getch(); switch(input) { - case 10: // Enter - output = bs.value[bs.curr]; // -> buttvalues[selbutton] + case KEY_ENTER: + case 10: /* Enter */ + output = bs.value[bs.curr]; loop = false; break; - case 27: // Esc + case 27: /* Esc */ output = BSDDIALOG_ERROR; loop = false; break; - case '\t': // TAB + case '\t': /* TAB */ bs.curr = (bs.curr + 1) % bs.nbuttons; buttupdate = true; break; @@ -977,7 +1012,7 @@ bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, currH = (currH < nrights-1)? currH +1 : currH; padsupdate = true; break; - case ' ': // Space + case ' ': /* Space */ items[curr].on = ! items[curr].on; if (currV == LEFT) { if (nlefts > 1) @@ -1009,7 +1044,7 @@ bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols, delwin(leftwin); delwin(rightpad); delwin(rightwin); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } diff --git a/lib/messagebox.c b/lib/messagebox.c index 2920986b48a8..0f04eed11473 100644 --- a/lib/messagebox.c +++ b/lib/messagebox.c @@ -53,7 +53,7 @@ extern struct bsddialog_theme t; static int -message_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, +message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, char *text, struct buttons bs) { int maxword, maxline, nlines, line; @@ -65,10 +65,10 @@ message_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, *w = VBORDERS; /* buttons size */ *w += bs.nbuttons * bs.sizebutton; - *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0; + *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; /* text size */ - line = MIN(maxline + VBORDERS + t.texthmargin * 2, AUTO_WIDTH); - line = MAX(line, (int) (maxword + VBORDERS + t.texthmargin * 2)); + line = MIN(maxline + VBORDERS + t.text.hmargin * 2, AUTO_WIDTH); + line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2)); *w = MAX(*w, line); /* avoid terminal overflow */ *w = MIN(*w, widget_max_width(conf)); @@ -92,7 +92,7 @@ static int message_checksize(int rows, int cols, struct buttons bs) mincols = VBORDERS; mincols += bs.nbuttons * bs.sizebutton; - mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0; + mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; if (cols < mincols) RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "\ @@ -126,7 +126,7 @@ textupdate(WINDOW *widget, int y, int x, int h, int w, WINDOW *textpad, } static int -do_widget(struct bsddialog_conf conf, char *text, int rows, int cols, +do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, struct buttons bs, bool shortkey) { WINDOW *widget, *textpad, *shadow; @@ -167,13 +167,13 @@ do_widget(struct bsddialog_conf conf, char *text, int rows, int cols, buttonsupdate(widget, h, w, bs, shortkey); break; case KEY_F(1): - if (conf.hfile == NULL) + if (conf->hfile == NULL) break; if (f1help(conf) != 0) return BSDDIALOG_ERROR; /* No break! the terminal size can change */ case KEY_RESIZE: - hide_widget(y, x, h, w,conf.shadow); + hide_widget(y, x, h, w,conf->shadow); /* * Unnecessary, but, when the columns decrease the @@ -191,7 +191,7 @@ do_widget(struct bsddialog_conf conf, char *text, int rows, int cols, return BSDDIALOG_ERROR; wclear(shadow); - mvwin(shadow, y + t.shadowrows, x + t.shadowcols); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); wresize(shadow, h, w); wclear(widget); @@ -200,11 +200,11 @@ do_widget(struct bsddialog_conf conf, char *text, int rows, int cols, htextpad = 1; wclear(textpad); - wresize(textpad, 1, w - HBORDERS - t.texthmargin * 2); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); if(update_widget_withtextpad(conf, shadow, widget, h, w, RAISED, textpad, &htextpad, text, true) != 0) - return BSDDIALOG_ERROR; + return BSDDIALOG_ERROR; buttonsupdate(widget, h, w, bs, shortkey); textupdate(widget, y, x, h, w, textpad, htextpad, textrow); @@ -256,7 +256,7 @@ do_widget(struct bsddialog_conf conf, char *text, int rows, int cols, /* API */ int -bsddialog_msgbox(struct bsddialog_conf conf, char* text, int rows, int cols) +bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols) { struct buttons bs; @@ -267,7 +267,7 @@ bsddialog_msgbox(struct bsddialog_conf conf, char* text, int rows, int cols) } int -bsddialog_yesno(struct bsddialog_conf conf, char* text, int rows, int cols) +bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols) { struct buttons bs; diff --git a/lib/textbox.c b/lib/textbox.c index 2874aa5832b9..481256fefc8a 100644 --- a/lib/textbox.c +++ b/lib/textbox.c @@ -40,16 +40,14 @@ #include "lib_util.h" #include "bsddialog_theme.h" -/* "Text": tailbox - tailboxbg - textbox */ +/* "Text": textbox */ #define BUTTON_TEXTBOX "HELP" extern struct bsddialog_theme t; -enum textmode { TAILMODE, TAILBGMODE, TEXTMODE}; - static void -textbox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, +textbox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, int hpad, int wpad) { @@ -70,7 +68,7 @@ textbox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w, } } -static int textbox_checksize(int rows, int cols, int hpad, int wpad) +static int textbox_checksize(int rows, int cols, int hpad) { int mincols; @@ -85,8 +83,8 @@ static int textbox_checksize(int rows, int cols, int hpad, int wpad) return 0; } -static int -do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, int cols) +int +bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols) { WINDOW *widget, *pad, *shadow; int i, input, y, x, h, w, hpad, wpad, ypad, xpad, ys, ye, xs, xe, printrows; @@ -95,26 +93,13 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, bool loop; int output; - if (mode == TAILMODE || mode == TAILBGMODE) { - bsddialog_msgbox(conf, "Tailbox and Tailboxbg unimplemented", rows, cols); - RETURN_ERROR("Tailbox and Tailboxbg unimplemented"); - } - - if ((fp = fopen(path, "r")) == NULL) + if ((fp = fopen(file, "r")) == NULL) RETURN_ERROR("Cannot open file"); - /*if (mode == TAILMODE) { - fseek (fp, 0, SEEK_END); - i = nlines = 0; - while (i < hpad) { - line = ; - } - for (i=hpad-1; i--; i>=0) { - } - }*/ + hpad = 1; wpad = 1; pad = newpad(hpad, wpad); - wbkgd(pad, t.widgetcolor); + wbkgd(pad, t.widget.color); i = 0; while(fgets(buf, BUFSIZ, fp) != NULL) { if ((int) strlen(buf) > wpad) { @@ -133,7 +118,7 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, if (set_widget_size(conf, rows, cols, &h, &w) != 0) return BSDDIALOG_ERROR; textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad); - if (textbox_checksize(h, w, hpad, wpad) != 0) + if (textbox_checksize(h, w, hpad) != 0) return BSDDIALOG_ERROR; if (set_widget_position(conf, &y, &x, h, w) != 0) return BSDDIALOG_ERROR; @@ -142,9 +127,9 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, NULL, NULL, NULL, true) != 0) return BSDDIALOG_ERROR; - exitbutt = conf.button.exit_label == NULL ? BUTTON_TEXTBOX : conf.button.exit_label; + exitbutt = conf->button.exit_label == NULL ? BUTTON_TEXTBOX : conf->button.exit_label; draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2, strlen(exitbutt)+2, - exitbutt, true, true); + exitbutt, true, false); wrefresh(widget); @@ -202,13 +187,13 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, ypad = ypad + printrows <= hpad -1 ? ypad + 1 : ypad; break; case KEY_F(1): - if (conf.hfile == NULL) + if (conf->hfile == NULL) break; if (f1help(conf) != 0) return BSDDIALOG_ERROR; /* No break! the terminal size can change */ case KEY_RESIZE: - hide_widget(y, x, h, w,conf.shadow); + hide_widget(y, x, h, w,conf->shadow); /* * Unnecessary, but, when the columns decrease the @@ -219,13 +204,13 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, if (set_widget_size(conf, rows, cols, &h, &w) != 0) return BSDDIALOG_ERROR; textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad); - if (textbox_checksize(h, w, hpad, wpad) != 0) + if (textbox_checksize(h, w, hpad) != 0) return BSDDIALOG_ERROR; if (set_widget_position(conf, &y, &x, h, w) != 0) return BSDDIALOG_ERROR; wclear(shadow); - mvwin(shadow, y + t.shadowrows, x + t.shadowcols); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); wresize(shadow, h, w); wclear(widget); @@ -244,7 +229,7 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, return BSDDIALOG_ERROR; draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2, - strlen(exitbutt)+2, exitbutt, true, true); + strlen(exitbutt)+2, exitbutt, true, false); wrefresh(widget); /* for button */ @@ -258,23 +243,3 @@ do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, return output; } - -int bsddialog_tailbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - - return (do_textbox(TAILMODE, conf, text, rows, cols)); -} - -int bsddialog_tailboxbg(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - - return (do_textbox(TAILBGMODE, conf, text, rows, cols)); -} - - -int bsddialog_textbox(struct bsddialog_conf conf, char* text, int rows, int cols) -{ - - return (do_textbox(TEXTMODE, conf, text, rows, cols)); -} - diff --git a/lib/theme.c b/lib/theme.c index 7c27a85af74f..f204729ab4c1 100644 --- a/lib/theme.c +++ b/lib/theme.c @@ -42,213 +42,172 @@ struct bsddialog_theme t; static struct bsddialog_theme bsddialogtheme = { #define bgwidget COLOR_WHITE #define bgcurr COLOR_YELLOW - .shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK), - .shadowrows = 1, - .shadowcols = 2, - - .backgroundcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - .surroundtitle = true, - .titlecolor = GET_COLOR(COLOR_YELLOW, bgwidget), - .lineraisecolor = GET_COLOR(COLOR_BLACK, bgwidget), - .linelowercolor = GET_COLOR(COLOR_BLACK, bgwidget), - .widgetcolor = GET_COLOR(COLOR_BLACK, bgwidget), - - .texthmargin = 1, - - .curritemcolor = GET_COLOR(COLOR_WHITE, bgcurr), - .itemcolor = GET_COLOR(COLOR_BLACK, bgwidget), - .currtagcolor = GET_COLOR(COLOR_BLACK, bgcurr), - .tagcolor = GET_COLOR(COLOR_YELLOW, bgwidget), - .namesepcolor = GET_COLOR(COLOR_YELLOW, bgwidget), - .descsepcolor = GET_COLOR(COLOR_YELLOW, bgwidget), - - .currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE), - .fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN), - .fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE), - - .currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE), - .barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE), - - .buttonspace = 3, - .buttleftch = '[', - .buttrightchar = ']', - .currbuttdelimcolor = GET_COLOR(COLOR_WHITE, bgcurr), - .buttdelimcolor = GET_COLOR(COLOR_BLACK, bgwidget), - .currbuttoncolor = GET_COLOR(COLOR_WHITE, bgcurr) | A_UNDERLINE, - .buttoncolor = GET_COLOR(COLOR_BLACK, bgwidget) | A_UNDERLINE, - .currshortkeycolor = GET_COLOR(COLOR_BLACK, bgcurr) | A_UNDERLINE, - .shortkeycolor = GET_COLOR(COLOR_YELLOW, bgwidget) | A_UNDERLINE, - - .bottomtitlecolor= GET_COLOR(COLOR_BLACK, bgwidget) + .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK), + .shadow.h = 1, + .shadow.w = 2, + + .terminal.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN), + .widget.delimtitle = true, + .widget.titlecolor = GET_COLOR(COLOR_YELLOW, bgwidget), + .widget.lineraisecolor = GET_COLOR(COLOR_BLACK, bgwidget), + .widget.linelowercolor = GET_COLOR(COLOR_BLACK, bgwidget), + .widget.color = GET_COLOR(COLOR_BLACK, bgwidget), + .widget.bottomtitlecolor = GET_COLOR(COLOR_BLACK, bgwidget), + + .text.hmargin = 1, + + .menu.arrowcolor = GET_COLOR(COLOR_YELLOW, bgwidget), + .menu.f_desccolor = GET_COLOR(COLOR_WHITE, bgcurr), + .menu.desccolor = GET_COLOR(COLOR_BLACK, bgwidget), + .menu.f_namecolor = GET_COLOR(COLOR_BLACK, bgcurr), + .menu.namecolor = GET_COLOR(COLOR_YELLOW, bgwidget), + .menu.namesepcolor = GET_COLOR(COLOR_YELLOW, bgwidget), + .menu.descsepcolor = GET_COLOR(COLOR_YELLOW, bgwidget), + + .form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE), + .form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN), + .form.readonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE), + + .bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE), + .bar.color = GET_COLOR(COLOR_BLUE, COLOR_WHITE), + + .button.space = 3, + .button.leftch = '[', + .button.rightch = ']', + .button.f_delimcolor = GET_COLOR(COLOR_WHITE, bgcurr), + .button.delimcolor = GET_COLOR(COLOR_BLACK, bgwidget), + .button.f_color = GET_COLOR(COLOR_WHITE, bgcurr) | A_UNDERLINE, + .button.color = GET_COLOR(COLOR_BLACK, bgwidget) | A_UNDERLINE, + .button.f_shortcutcolor = GET_COLOR(COLOR_BLACK, bgcurr) | A_UNDERLINE, + .button.shortcutcolor = GET_COLOR(COLOR_YELLOW, bgwidget) | A_UNDERLINE }; static struct bsddialog_theme blackwhite = { #define bk COLOR_BLACK #define fg COLOR_WHITE - .shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK), - .shadowrows = 1, - .shadowcols = 2, - - .backgroundcolor = GET_COLOR(fg, bk), - .surroundtitle = true, - .titlecolor = GET_COLOR(fg, bk), - .lineraisecolor = GET_COLOR(fg, bk), - .linelowercolor = GET_COLOR(fg, bk), - .widgetcolor = GET_COLOR(fg, bk), - - .texthmargin = 1, - - .curritemcolor = GET_COLOR(fg, bk) | A_REVERSE, - .itemcolor = GET_COLOR(fg, bk), - .currtagcolor = GET_COLOR(fg, bk) | A_REVERSE, - .tagcolor = GET_COLOR(fg, bk), - .namesepcolor = GET_COLOR(fg, bk), - .descsepcolor = GET_COLOR(fg, bk), - - .currfieldcolor = GET_COLOR(fg, bk) | A_REVERSE, - .fieldcolor = GET_COLOR(fg, bk), - .fieldreadonlycolor = GET_COLOR(fg, bk), - - .currbarcolor = GET_COLOR(fg, bk) | A_REVERSE, - .barcolor = GET_COLOR(fg, bk), - - .buttonspace = 3, - .buttleftch = '[', - .buttrightchar = ']', - .currbuttdelimcolor = GET_COLOR(fg, bk), - .buttdelimcolor = GET_COLOR(fg, bk), - .currbuttoncolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE, - .buttoncolor = GET_COLOR(fg, bk) | A_UNDERLINE, - .currshortkeycolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE, - .shortkeycolor = GET_COLOR(fg, bk) | A_UNDERLINE, - - .bottomtitlecolor= GET_COLOR(fg, bk) + .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK), + .shadow.h = 1, + .shadow.w = 2, + + .terminal.color = GET_COLOR(fg, bk), + .widget.delimtitle = true, + .widget.titlecolor = GET_COLOR(fg, bk), + .widget.lineraisecolor = GET_COLOR(fg, bk), + .widget.linelowercolor = GET_COLOR(fg, bk), + .widget.color = GET_COLOR(fg, bk), + .widget.bottomtitlecolor = GET_COLOR(fg, bk), + + .text.hmargin = 1, + + .menu.arrowcolor = GET_COLOR(fg, bk), + .menu.f_desccolor = GET_COLOR(fg, bk) | A_REVERSE, + .menu.desccolor = GET_COLOR(fg, bk), + .menu.f_namecolor = GET_COLOR(fg, bk) | A_REVERSE, + .menu.namecolor = GET_COLOR(fg, bk), + .menu.namesepcolor = GET_COLOR(fg, bk), + .menu.descsepcolor = GET_COLOR(fg, bk), + + .form.f_fieldcolor = GET_COLOR(fg, bk) | A_REVERSE, + .form.fieldcolor = GET_COLOR(fg, bk), + .form.readonlycolor = GET_COLOR(fg, bk), + + .bar.f_color = GET_COLOR(fg, bk) | A_REVERSE, + .bar.color = GET_COLOR(fg, bk), + + .button.space = 3, + .button.leftch = '[', + .button.rightch = ']', + .button.f_delimcolor = GET_COLOR(fg, bk), + .button.delimcolor = GET_COLOR(fg, bk), + .button.f_color = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE, + .button.color = GET_COLOR(fg, bk) | A_UNDERLINE, + .button.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE, + .button.shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE }; static struct bsddialog_theme dialogtheme = { - .shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK), - .shadowrows = 1, - .shadowcols = 2, - - .backgroundcolor = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD, - .surroundtitle = false, - .titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, - .lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD, - .linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD, - .widgetcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE), - - .texthmargin = 1, - - .curritemcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .itemcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD, - .currtagcolor = GET_COLOR(COLOR_YELLOW,COLOR_BLUE) | A_BOLD, - .tagcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, - .namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE), - .descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE), - - .currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD, - .fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE)| A_BOLD, - - .currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, - - .buttonspace = 3, - .buttleftch = '<', - .buttrightchar = '>', - .currbuttdelimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .buttdelimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE), - .currbuttoncolor = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD, - .buttoncolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE), - .currshortkeycolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .shortkeycolor = GET_COLOR(COLOR_RED, COLOR_WHITE) | A_BOLD, - - .bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD -}; - -static struct bsddialog_theme magentatheme = { - .shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK), - .shadowrows = 1, - .shadowcols = 2, - - .backgroundcolor = GET_COLOR(COLOR_WHITE, COLOR_MAGENTA) | A_BOLD, - .surroundtitle = true, - .titlecolor = GET_COLOR(COLOR_RED, COLOR_CYAN), - .lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD, - .linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - .widgetcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - - .texthmargin = 1, - - .curritemcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .itemcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD, - .currtagcolor = GET_COLOR(COLOR_YELLOW,COLOR_BLUE) | A_BOLD, - .tagcolor = GET_COLOR(COLOR_BLUE, COLOR_CYAN) | A_BOLD, - .namesepcolor = GET_COLOR(COLOR_RED, COLOR_CYAN) | A_BOLD, - .descsepcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD, - - .currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD, - .fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE)| A_BOLD, - - .currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, - .barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, - - .buttonspace = 3, - .buttleftch = '<', - .buttrightchar = '>', - .currbuttdelimcolor = GET_COLOR(COLOR_WHITE, COLOR_RED) | A_BOLD, - .buttdelimcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - .currbuttoncolor = GET_COLOR(COLOR_WHITE, COLOR_RED), - .buttoncolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - .currshortkeycolor = GET_COLOR(COLOR_WHITE, COLOR_RED) | A_BOLD, - .shortkeycolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN), - - .bottomtitlecolor= GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD + .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK), + .shadow.h = 1, + .shadow.w = 2, + + .terminal.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD, + .widget.delimtitle = false, + .widget.titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, + .widget.lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD, + .widget.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD, + .widget.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE), + .widget.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD, + + .text.hmargin = 1, + + .menu.arrowcolor = GET_COLOR(COLOR_GREEN, COLOR_WHITE), + .menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, + .menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD, + .menu.f_namecolor = GET_COLOR(COLOR_YELLOW,COLOR_BLUE) | A_BOLD, + .menu.namecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, + .menu.namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE), + .menu.descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE), + + .form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, + .form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD, + .form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE)| A_BOLD, + + .bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, + .bar.color = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD, + + .button.space = 3, + .button.leftch = '<', + .button.rightch = '>', + .button.f_delimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, + .button.delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE), + .button.f_color = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD, + .button.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE), + .button.f_shortcutcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD, + .button.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE) | A_BOLD }; void bsddialog_set_theme(struct bsddialog_theme newtheme) { - t.shadowcolor = newtheme.shadowcolor; - t.shadowrows = newtheme.shadowrows; - t.shadowcols = newtheme.shadowcols; - - t.backgroundcolor = newtheme.backgroundcolor; - t.surroundtitle = newtheme.surroundtitle; - t.titlecolor = newtheme.titlecolor; - t.lineraisecolor = newtheme.lineraisecolor; - t.linelowercolor = newtheme.linelowercolor; - t.widgetcolor = newtheme.widgetcolor; - - t.texthmargin = newtheme.texthmargin; - - t.curritemcolor = newtheme.curritemcolor; - t.itemcolor = newtheme.itemcolor; - t.currtagcolor = newtheme.currtagcolor; - t.tagcolor = newtheme.tagcolor; - t.namesepcolor = newtheme.namesepcolor; - t.descsepcolor = newtheme.descsepcolor; - - t.currfieldcolor = newtheme.currfieldcolor; - t.fieldcolor = newtheme.fieldcolor; - t.fieldreadonlycolor = newtheme.fieldreadonlycolor; - - t.currbarcolor = newtheme.currbarcolor; - t.barcolor = newtheme.barcolor; - - t.buttonspace = newtheme.buttonspace; - t.buttleftch = newtheme.buttleftch; - t.buttrightchar = newtheme.buttrightchar; - t.currbuttdelimcolor = newtheme.currbuttdelimcolor; - t.buttdelimcolor = newtheme.buttdelimcolor; - t.currbuttoncolor = newtheme.currbuttoncolor; - t.buttoncolor = newtheme.buttoncolor; - t.currshortkeycolor = newtheme.currshortkeycolor; - t.shortkeycolor = newtheme.shortkeycolor; - - t.bottomtitlecolor = newtheme.bottomtitlecolor; - - bkgd(t.backgroundcolor); + t.shadow.color = newtheme.shadow.color; + t.shadow.h = newtheme.shadow.h; + t.shadow.w = newtheme.shadow.w; + + t.terminal.color = newtheme.terminal.color; + t.widget.delimtitle = newtheme.widget.delimtitle; + t.widget.titlecolor = newtheme.widget.titlecolor; + t.widget.lineraisecolor = newtheme.widget.lineraisecolor; + t.widget.linelowercolor = newtheme.widget.linelowercolor; + t.widget.color = newtheme.widget.color; + t.widget.bottomtitlecolor = newtheme.widget.bottomtitlecolor; + + t.text.hmargin = newtheme.text.hmargin; + + t.menu.arrowcolor = newtheme.menu.arrowcolor; + t.menu.f_desccolor = newtheme.menu.f_desccolor; + t.menu.desccolor = newtheme.menu.desccolor; + t.menu.f_namecolor = newtheme.menu.f_namecolor; + t.menu.namecolor = newtheme.menu.namecolor; + t.menu.namesepcolor = newtheme.menu.namesepcolor; + t.menu.descsepcolor = newtheme.menu.descsepcolor; + + t.form.f_fieldcolor = newtheme.form.f_fieldcolor; + t.form.fieldcolor = newtheme.form.fieldcolor; + t.form.readonlycolor = newtheme.form.readonlycolor; + + t.bar.f_color = newtheme.bar.f_color; + t.bar.color = newtheme.bar.color; + + t.button.space = newtheme.button.space; + t.button.leftch = newtheme.button.leftch; + t.button.rightch = newtheme.button.rightch; + t.button.f_delimcolor = newtheme.button.f_delimcolor; + t.button.delimcolor = newtheme.button.delimcolor; + t.button.f_color = newtheme.button.f_color; + t.button.color = newtheme.button.color; + t.button.f_shortcutcolor = newtheme.button.f_shortcutcolor; + t.button.shortcutcolor = newtheme.button.shortcutcolor; + + bkgd(t.terminal.color); refresh(); } @@ -264,8 +223,6 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) bsddialog_set_theme(blackwhite); else if (newtheme == BSDDIALOG_THEME_DIALOG) bsddialog_set_theme(dialogtheme); - else if (newtheme == BSDDIALOG_THEME_MAGENTA) - bsddialog_set_theme(magentatheme); else RETURN_ERROR("Unknow default theme"); @@ -273,7 +230,8 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) } int -bsddialog_color(enum bsddialog_color background, enum bsddialog_color foreground) +bsddialog_color(enum bsddialog_color background, + enum bsddialog_color foreground) { return GET_COLOR(background, foreground); diff --git a/lib/timebox.c b/lib/timebox.c index f7abfd8c0f31..4b1b8ee989a6 100644 --- a/lib/timebox.c +++ b/lib/timebox.c @@ -25,59 +25,146 @@ * SUCH DAMAGE. */ +#include <sys/param.h> + #ifdef PORTNCURSES #include <ncurses/curses.h> #else #include <curses.h> #endif +#include <ctype.h> +#include <string.h> + #include "bsddialog.h" #include "lib_util.h" +#include "bsddialog_theme.h" -/* "Time": timebox - calendar */ +#define MINWDATE 25 /* 23 wins + 2 VBORDERS */ +#define MINWTIME 16 /*14 wins + 2 VBORDERS */ +#define MINHEIGHT 8 /* 2 for text */ -int bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols, - unsigned int *hh, unsigned int *mm, unsigned int *ss) +/* "Time": timebox - datebox */ + +extern struct bsddialog_theme t; + +static int +datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, + int *w, int minw, char *text, struct buttons bs) { - WINDOW *widget, *shadow; - int i, input, output, y, x, sel; - struct buttons bs; - bool loop, buttupdate; + int maxword, maxline, nlines, line; - if (hh == NULL || mm == NULL || ss == NULL) - RETURN_ERROR("hh or mm or ss == NULL"); + if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0) + return BSDDIALOG_ERROR; + + if (cols == BSDDIALOG_AUTOSIZE) { + *w = VBORDERS; + /* buttons size */ + *w += bs.nbuttons * bs.sizebutton; + *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; + /* text size */ + line = maxline + VBORDERS + t.text.hmargin * 2; + line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2)); + *w = MAX(*w, line); + /* date windows */ + *w = MAX(*w, minw); + /* avoid terminal overflow */ + *w = MIN(*w, widget_max_width(conf) -1); + } + + if (rows == BSDDIALOG_AUTOSIZE) { + *h = MINHEIGHT; + if (maxword > 0) + *h += MAX(nlines, (*w / GET_ASPECT_RATIO(conf))); + /* avoid terminal overflow */ + *h = MIN(*h, widget_max_height(conf) -1); + } + + return 0; +} + +static int +datetime_checksize(int rows, int cols, char *text, int minw, struct buttons bs) +{ + int mincols; + + mincols = VBORDERS; + mincols += bs.nbuttons * bs.sizebutton; + mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; + mincols = MAX(minw, mincols); + + if (cols < mincols) + RETURN_ERROR("Few cols for this timebox/datebox"); + + if (rows < MINHEIGHT + (strlen(text) > 0 ? 1 : 0)) + RETURN_ERROR("Few rows for this timebox/datebox"); + return 0; +} + +int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int *hh, unsigned int *mm, unsigned int *ss) +{ + WINDOW *widget, *textpad, *shadow; + int i, input, output, y, x, h, w, sel, htextpad; + struct buttons bs; + bool loop; struct myclockstruct { unsigned int max; - unsigned int curr; + unsigned int value; WINDOW *win; - } c[3] = { {23, *hh, NULL}, {59, *mm, NULL}, {59, *ss, NULL} }; + }; - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; + if (hh == NULL || mm == NULL || ss == NULL) + RETURN_ERROR("hh / mm / ss cannot be NULL"); + + struct myclockstruct c[3] = { + {23, *hh, NULL}, + {59, *mm, NULL}, + {59, *ss, NULL} + }; - c[0].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 7, 3, 4, LOWERED); - mvwaddch(widget, rows - 5, cols/2 - 3, ':'); - c[1].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 2, 3, 4, LOWERED); - mvwaddch(widget, rows - 5, cols/2 + 2, ':'); - c[2].win = new_boxed_window(conf, y + rows - 6, x + cols/2 + 3, 3, 4, LOWERED); + for (i = 0 ; i < 3; i++) { + if (c[i].value > c[i].max) + c[i].value = c[i].max; + } get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - sel=0; + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0) + return BSDDIALOG_ERROR; + if (datetime_checksize(h, w, text, MINWTIME, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + draw_buttons(widget, h-2, w, bs, true); + + wrefresh(widget); + + prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); + + c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 7, 3, 4, LOWERED); + mvwaddch(widget, h - 5, w/2 - 3, ':'); + c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 2, 3, 4, LOWERED); + mvwaddch(widget, h - 5, w/2 + 2, ':'); + c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 3, 3, 4, LOWERED); + + wrefresh(widget); + + sel = 0; curs_set(2); - loop = buttupdate = true; + loop = true; while(loop) { - if (buttupdate) { - draw_buttons(widget, rows-2, cols, bs, true); - wrefresh(widget); - buttupdate = false; - } - for (i=0; i<3; i++) { - mvwprintw(c[i].win, 1, 1, "%2d", c[i].curr); + mvwprintw(c[i].win, 1, 1, "%2d", c[i].value); wrefresh(c[i].win); } wmove(c[sel].win, 1, 2); @@ -85,12 +172,13 @@ int bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols input = getch(); switch(input) { + case KEY_ENTER: case 10: /* Enter */ output = bs.value[bs.curr]; if (output == BSDDIALOG_YESOK) { - *hh = c[0].curr - 1900; - *mm = c[1].curr; - *ss = c[2].curr; + *hh = c[0].value; + *mm = c[1].value; + *ss = c[2].value; } loop = false; break; @@ -104,21 +192,98 @@ int bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols case KEY_LEFT: if (bs.curr > 0) { bs.curr--; - buttupdate = true; + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); } break; case KEY_RIGHT: if (bs.curr < (int) bs.nbuttons - 1) { bs.curr++; - buttupdate = true; + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); } break; case KEY_UP: - c[sel].curr = c[sel].curr < c[sel].max ? c[sel].curr + 1 : 0; + c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 0; break; case KEY_DOWN: - c[sel].curr = c[sel].curr > 0 ? c[sel].curr - 1 : c[sel].max; + c[sel].value = c[sel].value > 0 ? c[sel].value - 1 : c[sel].max; + break; + case KEY_F(1): + if (conf->hfile == NULL) + break; + curs_set(0); + if (f1help(conf) != 0) + return BSDDIALOG_ERROR; + curs_set(2); + /* No break! the terminal size can change */ + case KEY_RESIZE: + hide_widget(y, x, h, w,conf->shadow); + + /* + * Unnecessary, but, when the columns decrease the + * following "refresh" seem not work + */ + refresh(); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0) + return BSDDIALOG_ERROR; + if (datetime_checksize(h, w, text, MINWTIME, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + wclear(shadow); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); + wresize(shadow, h, w); + + wclear(widget); + mvwin(widget, y, x); + wresize(widget, h, w); + + htextpad = 1; + wclear(textpad); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); + + if(update_widget_withtextpad(conf, shadow, widget, h, w, + RAISED, textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + mvwaddch(widget, h - 5, w/2 - 3, ':'); + mvwaddch(widget, h - 5, w/2 + 2, ':'); + + draw_buttons(widget, h-2, w, bs, true); + + wrefresh(widget); + + prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); + + wclear(c[0].win); + mvwin(c[0].win, y + h - 6, x + w/2 - 7); + draw_borders(conf, c[0].win, 3, 4, LOWERED); + wrefresh(c[0].win); + + wclear(c[1].win); + mvwin(c[1].win, y + h - 6, x + w/2 - 2); + draw_borders(conf, c[1].win, 3, 4, LOWERED); + wrefresh(c[1].win); + + wclear(c[2].win); + mvwin(c[2].win, y + h - 6, x + w/2 + 3); + draw_borders(conf, c[2].win, 3, 4, LOWERED); + wrefresh(c[2].win); + + /* Important to avoid grey lines expanding screen */ + refresh(); break; + default: + for (i = 0; i < (int) bs.nbuttons; i++) + if (tolower(input) == tolower((bs.label[i])[0])) { + output = bs.value[i]; + loop = false; + } } } @@ -126,66 +291,97 @@ int bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols for (i=0; i<3; i++) delwin(c[i].win); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } -int bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int cols, +int +bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd) { - WINDOW *widget, *shadow; - int i, input, output, y, x, sel; + WINDOW *widget, *textpad, *shadow; + int i, input, output, y, x, h, w, sel, htextpad; struct buttons bs; - bool loop, buttupdate; - - if (yy == NULL || mm == NULL || dd == NULL) - RETURN_ERROR("yy or mm or dd == NULL"); - + bool loop; struct calendar { - unsigned int max; - unsigned int curr; + int max; + int value; WINDOW *win; unsigned int x; - } c[3] = {{9999, *yy, NULL, 4 }, {12, *mm, NULL, 9 }, {31, *dd, NULL, 2 }}; + }; struct month { char *name; unsigned int days; - } m[12] = { - { "January", 30 }, { "February", 30 }, { "March", 30 }, - { "April", 30 }, { "May", 30 }, { "June", 30 }, - { "July", 30 }, { "August", 30 }, { "September", 30 }, - { "October", 30 }, { "November", 30 }, { "December", 30 } }; - if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow, - true) <0) - return -1; + if (yy == NULL || mm == NULL || dd == NULL) + RETURN_ERROR("yy / mm / dd cannot be NULL"); + + struct calendar c[3] = { + {9999, *yy, NULL, 4 }, + {12, *mm, NULL, 9 }, + {31, *dd, NULL, 2 } + }; + + struct month m[12] = { + { "January", 31 }, { "February", 28 }, { "March", 31 }, + { "April", 30 }, { "May", 31 }, { "June", 30 }, + { "July", 31 }, { "August", 31 }, { "September", 30 }, + { "October", 31 }, { "November", 30 }, { "December", 31 } + }; - c[0].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 12, 3, 6, LOWERED); - mvwaddch(widget, rows - 5, cols/2 - 6, '/'); - c[1].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 5, 3, 11, LOWERED); - mvwaddch(widget, rows - 5, cols/2 + 6, '/'); - c[2].win = new_boxed_window(conf, y + rows - 6, x + cols/2 + 7, 3, 4, LOWERED); +#define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) - wrefresh(widget); + for (i = 0 ; i < 3; i++) { + if (c[i].value > c[i].max) + c[i].value = c[i].max; + if (c[i].value < 1) + c[i].value = 1; + } + c[2].max = m[c[1].value -1].days; + if (c[1].value == 2 && ISLEAF(c[0].value)) + c[2].max = 29; + if (c[2].value > c[2].max) + c[2].value = c[2].max; get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); - sel=2; + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0) + return BSDDIALOG_ERROR; + if (datetime_checksize(h, w, text, MINWDATE, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, + &textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + draw_buttons(widget, h-2, w, bs, true); + + wrefresh(widget); + + prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); + + c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 11, 3, 6, LOWERED); + mvwaddch(widget, h - 5, w/2 - 5, '/'); + c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 4, 3, 11, LOWERED); + mvwaddch(widget, h - 5, w/2 + 7, '/'); + c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 8, 3, 4, LOWERED); + + wrefresh(widget); + + sel = 2; curs_set(2); - loop = buttupdate = true; + loop = true; while(loop) { - if (buttupdate) { - draw_buttons(widget, rows-2, cols, bs, true); - wrefresh(widget); - buttupdate = false; - } - - mvwprintw(c[0].win, 1, 1, "%4d", c[0].curr); - mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].curr-1].name); - mvwprintw(c[2].win, 1, 1, "%2d", c[2].curr); + mvwprintw(c[0].win, 1, 1, "%4d", c[0].value); + mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name); + mvwprintw(c[2].win, 1, 1, "%2d", c[2].value); for (i=0; i<3; i++) { wrefresh(c[i].win); } @@ -194,40 +390,134 @@ int bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int col input = getch(); switch(input) { - case 10: // Enter - output = bs.value[bs.curr]; // values -> outputs + case KEY_ENTER: + case 10: /* Enter */ + output = bs.value[bs.curr]; if (output == BSDDIALOG_YESOK) { - *yy = c[0].curr - 1900; - *mm = c[1].curr; - *dd = c[2].curr; + *yy = c[0].value; + *mm = c[1].value; + *dd = c[2].value; } loop = false; break; - case 27: // Esc + case 27: /* Esc */ output = BSDDIALOG_ESC; loop = false; break; - case '\t': // TAB + case '\t': /* TAB */ sel = (sel + 1) % 3; break; case KEY_LEFT: if (bs.curr > 0) { bs.curr--; - buttupdate = true; + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); } break; case KEY_RIGHT: if (bs.curr < (int) bs.nbuttons - 1) { bs.curr++; - buttupdate = true; + draw_buttons(widget, h-2, w, bs, true); + wrefresh(widget); } break; case KEY_UP: - c[sel].curr = c[sel].curr < c[sel].max ? c[sel].curr + 1 : 1; + c[sel].value = c[sel].value > 1 ? c[sel].value - 1 : c[sel].max ; + /* if mount change */ + c[2].max = m[c[1].value -1].days; + /* if year change */ + if (c[1].value == 2 && ISLEAF(c[0].value)) + c[2].max = 29; + /* set new day */ + if (c[2].value > c[2].max) + c[2].value = c[2].max; break; case KEY_DOWN: - c[sel].curr = c[sel].curr > 1 ? c[sel].curr - 1 : c[sel].max; + c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 1; + /* if mount change */ + c[2].max = m[c[1].value -1].days; + /* if year change */ + if (c[1].value == 2 && ISLEAF(c[0].value)) + c[2].max = 29; + /* set new day */ + if (c[2].value > c[2].max) + c[2].value = c[2].max; + break; + case KEY_F(1): + if (conf->hfile == NULL) + break; + curs_set(0); + if (f1help(conf) != 0) + return BSDDIALOG_ERROR; + curs_set(2); + /* No break! the terminal size can change */ + case KEY_RESIZE: + hide_widget(y, x, h, w,conf->shadow); + + /* + * Unnecessary, but, when the columns decrease the + * following "refresh" seem not work + */ + refresh(); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return BSDDIALOG_ERROR; + if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0) + return BSDDIALOG_ERROR; + if (datetime_checksize(h, w, text, MINWDATE, bs) != 0) + return BSDDIALOG_ERROR; + if (set_widget_position(conf, &y, &x, h, w) != 0) + return BSDDIALOG_ERROR; + + wclear(shadow); + mvwin(shadow, y + t.shadow.h, x + t.shadow.w); + wresize(shadow, h, w); + + wclear(widget); + mvwin(widget, y, x); + wresize(widget, h, w); + + htextpad = 1; + wclear(textpad); + wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); + + if(update_widget_withtextpad(conf, shadow, widget, h, w, + RAISED, textpad, &htextpad, text, true) != 0) + return BSDDIALOG_ERROR; + + mvwaddch(widget, h - 5, w/2 - 5, '/'); + mvwaddch(widget, h - 5, w/2 + 7, '/'); + + draw_buttons(widget, h-2, w, bs, true); + + wrefresh(widget); + + prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); + + wclear(c[0].win); + mvwin(c[0].win, y + h - 6, x + w/2 - 11); + draw_borders(conf, c[0].win, 3, 6, LOWERED); + wrefresh(c[0].win); + + wclear(c[1].win); + mvwin(c[1].win, y + h - 6, x + w/2 - 4); + draw_borders(conf, c[1].win, 3, 11, LOWERED); + wrefresh(c[1].win); + + wclear(c[2].win); + mvwin(c[2].win, y + h - 6, x + w/2 + 8); + draw_borders(conf, c[2].win, 3, 4, LOWERED); + wrefresh(c[2].win); + + /* Important to avoid grey lines expanding screen */ + refresh(); break; + default: + for (i = 0; i < (int) bs.nbuttons; i++) + if (tolower(input) == tolower((bs.label[i])[0])) { + output = bs.value[i]; + loop = false; + } } } @@ -235,7 +525,7 @@ int bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int col for (i=0; i<3; i++) delwin(c[i].win); - end_widget(conf, widget, rows, cols, shadow); + end_widget_withtextpad(conf, widget, h, w, textpad, shadow); return output; } |