diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/GNUMakefile | 10 | ||||
| -rw-r--r-- | lib/Makefile | 6 | ||||
| -rw-r--r-- | lib/barbox.c | 2 | ||||
| -rw-r--r-- | lib/bsddialog.3 | 33 | ||||
| -rw-r--r-- | lib/bsddialog.h | 10 | ||||
| -rw-r--r-- | lib/calendarbox.c | 520 | ||||
| -rw-r--r-- | lib/formbox.c | 29 | ||||
| -rw-r--r-- | lib/lib_util.c | 14 | ||||
| -rw-r--r-- | lib/lib_util.h | 3 | ||||
| -rw-r--r-- | lib/libbsddialog.c | 4 | ||||
| -rw-r--r-- | lib/menubox.c | 50 | ||||
| -rw-r--r-- | lib/messagebox.c | 42 | ||||
| -rw-r--r-- | lib/theme.c | 1 | ||||
| -rw-r--r-- | lib/timebox.c | 20 |
14 files changed, 645 insertions, 99 deletions
diff --git a/lib/GNUMakefile b/lib/GNUMakefile index 1d55d6edd60d..3c31c78fdf88 100644 --- a/lib/GNUMakefile +++ b/lib/GNUMakefile @@ -3,15 +3,15 @@ # # Written in 2021 by Alfonso Sabato Siciliano -VERSION = 0.3 +VERSION = 0.4 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h -SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ - messagebox.c textbox.c theme.c timebox.c +SOURCES = barbox.c calendarbox.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 = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra -Wno-implicit-fallthrough \ - -Werror -fpic +CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra \ + -Wno-implicit-fallthrough -Werror -fpic LDFLAGS = -lncursesw -ltinfo LIBFLAG = -shared diff --git a/lib/Makefile b/lib/Makefile index 5c535c5483f1..0f536fb38743 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -3,13 +3,13 @@ # # Written in 2021 by Alfonso Sabato Siciliano -VERSION = 0.3 +VERSION = 0.4 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} LIBRARY_A = lib${LIBRARY:=.a} HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h -SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ - messagebox.c textbox.c theme.c timebox.c +SOURCES = barbox.c calendarbox.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 += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \ diff --git a/lib/barbox.c b/lib/barbox.c index b6bfe32fc0aa..71759839a709 100644 --- a/lib/barbox.c +++ b/lib/barbox.c @@ -327,7 +327,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols, wrefresh(bar); - /* getch(); port ncurses shows nothing */ + /* getch(); alternate mode (port devel/ncurses) shows nothing */ delwin(bar); end_dialog(conf, shadow, widget, textpad); diff --git a/lib/bsddialog.3 b/lib/bsddialog.3 index 12db1f039d59..9cc68a90ff62 100644 --- a/lib/bsddialog.3 +++ b/lib/bsddialog.3 @@ -22,11 +22,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 29, 2022 +.Dd September 23, 2022 .Dt BSDDIALOG 3 .Os .Sh NAME .Nm bsddialog_backtitle , +.Nm bsddialog_calendar , .Nm bsddialog_clearterminal , .Nm bsddialog_color , .Nm bsddialog_color_attrs , @@ -62,6 +63,16 @@ .Ft int .Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle" .Ft int +.Fo bsddialog_calendar +.Fa "struct bsddialog_conf *conf" +.Fa "const char *text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int *yy" +.Fa "unsigned int *mm" +.Fa "unsigned int *dd" +.Fc +.Ft int .Fo bsddialog_checklist .Fa "struct bsddialog_conf *conf" .Fa "const char *text" @@ -75,7 +86,7 @@ .Ft int .Fn bsddialog_clearterminal "void" .Ft int -.Fo bsddialog_datebox" +.Fo bsddialog_datebox .Fa "struct bsddialog_conf *conf" .Fa "const char *text" .Fa "int rows" @@ -476,7 +487,8 @@ function. buttons always active, avoidind focus switch between buttons and input fields or input boxes in .Fn bsddialog_form , -.Fn bsddialog_datebox +.Fn bsddialog_datebox , +.Fn bsddialog_calendar and .Fn bsddialog_timebox . .It Fa conf.button.without_ok @@ -515,7 +527,10 @@ to true, and .Fa conf.x to -.Dv BSDDIALOG_CENTER . +.Dv BSDDIALOG_CENTER , +.Fa conf.text.cols_per_row +to +.Dv 10 . .Pp .Fn bsddialog_infobox builds a dialog without buttons and returns instantly. @@ -531,8 +546,10 @@ builds a dialog waiting until the timeout in .Fa seconds expires or a button is pressed. .Pp +.Fn bsddialog_calendar +and .Fn bsddialog_datebox -builds a dialog to select a date, +build a dialog to select a date, .Fa yy , .Fa mm , and @@ -606,14 +623,14 @@ builds a dialog with collections of checklists, radiolists and separators. A collection is a set defined like: .Pp .Bd -literal -offset indent -compact -enum bsddialog_grouptype { +enum bsddialog_menutype { BSDDIALOG_CHECKLIST, BSDDIALOG_RADIOLIST, BSDDIALOG_SEPARATOR, }; struct bsddialog_menugroup { - enum bsddialog_grouptype type; + enum bsddialog_menutype type; unsigned int nitems; struct bsddialog_menuitem *items; }; @@ -1013,7 +1030,7 @@ struct bsddialog_menuitem check[2] = { struct bsddialog_menuitem sep[1] = { { "3", true, 0, "Radiolist", "(desc)", "" } }; -struct bsddialog_menuitem radio[5] = { +struct bsddialog_menuitem radio[2] = { { "4", true, 0, "Name 1", "Desc 1", "Radio Bottom Desc 1" }, { "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" } }; diff --git a/lib/bsddialog.h b/lib/bsddialog.h index 6f13da3fa667..ce6aac6d4632 100644 --- a/lib/bsddialog.h +++ b/lib/bsddialog.h @@ -30,7 +30,7 @@ #include <stdbool.h> -#define LIBBSDDIALOG_VERSION "0.3" +#define LIBBSDDIALOG_VERSION "0.4" /* Exit status */ #define BSDDIALOG_ERROR -1 @@ -136,14 +136,14 @@ struct bsddialog_menuitem { const char *bottomdesc; }; -enum bsddialog_grouptype { +enum bsddialog_menutype { BSDDIALOG_CHECKLIST, BSDDIALOG_RADIOLIST, BSDDIALOG_SEPARATOR, }; struct bsddialog_menugroup { - enum bsddialog_grouptype type; + enum bsddialog_menutype type; unsigned int nitems; struct bsddialog_menuitem *items; }; @@ -174,6 +174,10 @@ const char *bsddialog_geterror(void); /* Dialogs */ int +bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows, + int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd); + +int bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows, int cols, unsigned int menurows, unsigned int nitems, struct bsddialog_menuitem *items, int *focusitem); diff --git a/lib/calendarbox.c b/lib/calendarbox.c new file mode 100644 index 000000000000..3b55b26a13b8 --- /dev/null +++ b/lib/calendarbox.c @@ -0,0 +1,520 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 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 <sys/param.h> + +#include <curses.h> +#include <stdlib.h> +#include <string.h> + +#include "bsddialog.h" +#include "bsddialog_theme.h" +#include "lib_util.h" + +#define MINHCAL 13 +#define MINWCAL 36 /* 34 calendar, 1 + 1 margins */ +#define MINYEAR 1900 +#define MAXYEAR 999999999 + +static int month_days(int yy, int mm) +{ + int days; + + if (mm == 2) + days = ISLEAP(yy) ? 29 : 28; + else if (mm == 4 || mm == 6 || mm == 9 || mm == 11) + days = 30; + else + days = 31; + + return (days); +} + +enum operation { + UP_DAY, + DOWN_DAY, + LEFT_DAY, + RIGHT_DAY, + UP_MONTH, + DOWN_MONTH, + UP_YEAR, + DOWN_YEAR +}; + +static void datectl(enum operation op, int *yy, int *mm, int *dd) +{ + int ndays; + + ndays = month_days(*yy, *mm); + + switch (op) { + case UP_DAY: + if (*dd > 7) + *dd -= 7; + else { + if (*mm == 1) { + *yy -= 1; + *mm = 12; + } else + *mm -= 1; + ndays = month_days(*yy, *mm); + *dd = ndays - abs(7 - *dd); + } + break; + case DOWN_DAY: + if (*dd + 7 < ndays) + *dd += 7; + else { + if (*mm == 12) { + *yy += 1; + *mm = 1; + } else + *mm += 1; + *dd = *dd + 7 - ndays; + } + break; + case LEFT_DAY: + if (*dd > 1) + *dd -= 1; + else { + if (*mm == 1) { + *yy -= 1; + *mm = 12; + } else + *mm -= 1; + *dd = month_days(*yy, *mm); + } + break; + case RIGHT_DAY: + if (*dd < ndays) + *dd += 1; + else { + if (*mm == 12) { + *yy += 1; + *mm = 1; + } else + *mm += 1; + *dd = 1; + } + break; + case UP_MONTH: + if (*mm == 1) { + *mm = 12; + *yy -= 1; + } else + *mm -= 1; + ndays = month_days(*yy, *mm); + if (*dd > ndays) + *dd = ndays; + break; + case DOWN_MONTH: + if (*mm == 12) { + *mm = 1; + *yy += 1; + } else + *mm += 1; + ndays = month_days(*yy, *mm); + if (*dd > ndays) + *dd = ndays; + break; + case UP_YEAR: + *yy -= 1; + ndays = month_days(*yy, *mm); + if (*dd > ndays) + *dd = ndays; + break; + case DOWN_YEAR: + *yy += 1; + ndays = month_days(*yy, *mm); + if (*dd > ndays) + *dd = ndays; + break; + } + + if (*yy < MINYEAR) { + *yy = MINYEAR; + *mm = 1; + *dd = 1; + } + if (*yy > MAXYEAR) { + *yy = MAXYEAR; + *mm = 12; + *dd = 31; + } +} + +static int week_day(int yy, int mm, int dd) +{ + int wd; + + dd += mm < 3 ? yy-- : yy - 2; + wd = 23*mm/9 + dd + 4 + yy/4 - yy/100 + yy/400; + wd %= 7; + + return (wd); +} + +static void +print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd, + bool active) +{ + int ndays, i, y, x, wd, h, w; + + getmaxyx(win, h, w); + wclear(win); + draw_borders(conf, win, h, w, RAISED); + if (active) { + wattron(win, t.dialog.arrowcolor); + mvwhline(win, 0, 15, conf->ascii_lines ? '^' : ACS_UARROW, 4); + mvwhline(win, h-1, 15, conf->ascii_lines ? 'v' : ACS_DARROW, 4); + mvwvline(win, 3, 0, conf->ascii_lines ? '<' : ACS_LARROW, 3); + mvwvline(win, 3, w-1, conf->ascii_lines ? '>' : ACS_RARROW, 3); + wattroff(win, t.dialog.arrowcolor); + } + + mvwaddstr(win, 1, 5, "Sun Mon Tue Wed Thu Fri Sat"); + ndays = month_days(yy, mm); + y = 2; + wd = week_day(yy, mm, 1); + for (i = 1; i <= ndays; i++) { + x = 5 + (4 * wd); /* x has to be 6 with week number */ + wmove(win, y, x); + mvwprintw(win, y, x, "%2d", i); + if (i == dd) { + wattron(win, t.menu.f_namecolor); + mvwprintw(win, y, x, "%2d", i); + wattroff(win, t.menu.f_namecolor); + } + wd++; + if (wd > 6) { + wd = 0; + y++; + } + } + + wrefresh(win); +} + +static void +drawsquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt, + const void *value, bool focus) +{ + int h, w; + + getmaxyx(win, h, w); + draw_borders(conf, win, h, w, RAISED); + if (focus) { + wattron(win, t.dialog.arrowcolor); + mvwhline(win, 0, 7, conf->ascii_lines ? '^' : ACS_UARROW, 3); + mvwhline(win, 2, 7, conf->ascii_lines ? 'v' : ACS_DARROW, 3); + wattroff(win, t.dialog.arrowcolor); + } + + if (focus) + wattron(win, t.menu.f_namecolor); + if (strchr(fmt, 's') != NULL) + mvwprintw(win, 1, 1, fmt, (const char*)value); + else + mvwprintw(win, 1, 1, fmt, *((const int*)value)); + if (focus) + wattroff(win, t.menu.f_namecolor); + + wrefresh(win); +} + +static int +calendar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, + int *w, const char *text, struct buttons bs) +{ + int htext, wtext; + + if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) { + if (text_size(conf, rows, cols, text, &bs, MINHCAL, MINWCAL, + &htext, &wtext) != 0) + return (BSDDIALOG_ERROR); + } + + if (cols == BSDDIALOG_AUTOSIZE) + *w = widget_min_width(conf, wtext, MINWCAL, &bs); + + if (rows == BSDDIALOG_AUTOSIZE) + *h = widget_min_height(conf, htext, MINHCAL, true); + + return (0); +} + +static int calendar_checksize(int rows, int cols, struct buttons bs) +{ + int mincols; + + mincols = MAX(MINWCAL, buttons_min_width(bs)); + mincols += VBORDERS; + + if (cols < mincols) + RETURN_ERROR("Few cols for this calendar (at least 38)"); + + if (rows < MINHCAL + 2 + 2) /* 2 buttons + 2 borders */ + RETURN_ERROR("Few rows for calendar (at least 17)"); + + return (0); +} + +int +bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows, + int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd) +{ + bool loop, focusbuttons; + int retval, y, x, h, w, sel, ycal, xcal, year, month, day; + wint_t input; + WINDOW *widget, *textpad, *shadow, *yearwin, *monthwin, *daywin; + struct buttons bs; + const char *m[12] = { + "January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December" + }; + + if (yy == NULL || mm == NULL || dd == NULL) + RETURN_ERROR("yy / mm / dd cannot be NULL"); + + year = *yy > MAXYEAR ? MAXYEAR : *yy; + if (year < MINYEAR) + year = MINYEAR; + month = *mm > 12 ? 12 : *mm; + if (month == 0) + month = 1; + day = *dd == 0 ? 1 : *dd; + if(day > month_days(year, month)) + day = month_days(year, month); + + get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return (BSDDIALOG_ERROR); + if (calendar_autosize(conf, rows, cols, &h, &w, text, bs) != 0) + return (BSDDIALOG_ERROR); + if (calendar_checksize(h, w, bs) != 0) + return (BSDDIALOG_ERROR); + if (set_widget_position(conf, &y, &x, h, w) != 0) + return (BSDDIALOG_ERROR); + + if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, + true) != 0) + return (BSDDIALOG_ERROR); + + pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-17, x+w-2); + doupdate(); + + ycal = y + h - 15; + xcal = x + w/2 - 17; + mvwaddstr(widget, h - 16, w/2 - 17, "Month"); + monthwin = new_boxed_window(conf, ycal, xcal, 3, 17, RAISED); + mvwaddstr(widget, h - 16, w/2, "Year"); + yearwin = new_boxed_window(conf, ycal, xcal + 17, 3, 17, RAISED); + daywin = new_boxed_window(conf, ycal + 3, xcal, 9, 34, RAISED); + + wrefresh(widget); + + sel = -1; + loop = focusbuttons = true; + while (loop) { + drawsquare(conf, monthwin, "%15s", m[month - 1], sel == 0); + drawsquare(conf, yearwin, "%15d", &year, sel == 1); + print_calendar(conf, daywin, year, month, day, sel == 2); + + if (get_wch(&input) == ERR) + continue; + switch(input) { + case KEY_ENTER: + case 10: /* Enter */ + if (focusbuttons || conf->button.always_active) { + retval = bs.value[bs.curr]; + loop = false; + } + break; + case 27: /* Esc */ + if (conf->key.enable_esc) { + retval = BSDDIALOG_ESC; + loop = false; + } + break; + case '\t': /* TAB */ + if (focusbuttons) { + bs.curr++; + if (bs.curr >= (int)bs.nbuttons) { + focusbuttons = false; + sel = 0; + bs.curr = conf->button.always_active ? + 0 : -1; + } + } else { + sel++; + if (sel > 2) { + focusbuttons = true; + sel = -1; + bs.curr = 0; + } + } + draw_buttons(widget, bs, true); + wrefresh(widget); + break; + case KEY_RIGHT: + if (focusbuttons) { + bs.curr++; + if (bs.curr >= (int)bs.nbuttons) { + focusbuttons = false; + sel = 0; + bs.curr = conf->button.always_active ? + 0 : -1; + } + } else if (sel == 2) { + datectl(RIGHT_DAY, &year, &month, &day); + } else { /* Month or Year*/ + sel++; + } + draw_buttons(widget, bs, true); + wrefresh(widget); + break; + case KEY_LEFT: + if (focusbuttons) { + bs.curr--; + if (bs.curr < 0) { + focusbuttons = false; + sel = 2; + bs.curr = conf->button.always_active ? + 0 : -1; + } + } else if (sel == 2) { + datectl(LEFT_DAY, &year, &month, &day); + } else if (sel == 1) { + sel = 0; + } else { /* sel = 0, Month */ + focusbuttons = true; + sel = -1; + bs.curr = 0; + } + draw_buttons(widget, bs, true); + wrefresh(widget); + break; + case KEY_UP: + if (focusbuttons) { + sel = 2; + focusbuttons = false; + bs.curr = conf->button.always_active ? 0 : -1; + draw_buttons(widget, bs, true); + wrefresh(widget); + } else if (sel == 0) { + datectl(UP_MONTH, &year, &month, &day); + } else if (sel == 1) { + datectl(UP_YEAR, &year, &month, &day); + } else { /* sel = 2 */ + datectl(UP_DAY, &year, &month, &day); + } + break; + case KEY_DOWN: + if (focusbuttons) { + break; + } else if (sel == 0) { + datectl(DOWN_MONTH, &year, &month, &day); + } else if (sel == 1) { + datectl(DOWN_YEAR, &year, &month, &day); + } else { /* sel = 2 */ + datectl(DOWN_DAY, &year, &month, &day); + } + break; + case KEY_HOME: + datectl(UP_MONTH, &year, &month, &day); + break; + case KEY_END: + datectl(DOWN_MONTH, &year, &month, &day); + break; + case KEY_PPAGE: + datectl(UP_YEAR, &year, &month, &day); + break; + case KEY_NPAGE: + datectl(DOWN_YEAR, &year, &month, &day); + break; + case KEY_F(1): + if (conf->key.f1_file == NULL && + conf->key.f1_message == NULL) + break; + if (f1help(conf) != 0) + return (BSDDIALOG_ERROR); + /* No break, screen size can change */ + case KEY_RESIZE: + /* Important for decreasing screen */ + hide_widget(y, x, h, w, conf->shadow); + refresh(); + + if (set_widget_size(conf, rows, cols, &h, &w) != 0) + return (BSDDIALOG_ERROR); + if (calendar_autosize(conf, rows, cols, &h, &w, text, + bs) != 0) + return (BSDDIALOG_ERROR); + if (calendar_checksize(h, w, bs) != 0) + return (BSDDIALOG_ERROR); + if (set_widget_position(conf, &y, &x, h, w) != 0) + return (BSDDIALOG_ERROR); + + if (update_dialog(conf, shadow, widget, y, x, h, w, + textpad, text, &bs, true) != 0) + return (BSDDIALOG_ERROR); + pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-17, x+w-2); + doupdate(); + + ycal = y + h - 15; + xcal = x + w/2 - 17; + mvwaddstr(widget, h - 16, w/2 - 17, "Month"); + mvwin(monthwin, ycal, xcal); + mvwaddstr(widget, h - 16, w/2, "Year"); + mvwin(yearwin, ycal, xcal + 17); + mvwin(daywin, ycal + 3, xcal); + wrefresh(widget); + + /* Important to avoid grey lines expanding screen */ + refresh(); + break; + default: + if (shortcut_buttons(input, &bs)) { + retval = bs.value[bs.curr]; + loop = false; + } + } + } + + if (retval == BSDDIALOG_OK) { + *yy = year; + *mm = month; + *dd = day; + } + + delwin(yearwin); + delwin(monthwin); + delwin(daywin); + end_dialog(conf, shadow, widget, textpad); + + return (retval); +}
\ No newline at end of file diff --git a/lib/formbox.c b/lib/formbox.c index cd29919417be..5b1d2ab61de2 100644 --- a/lib/formbox.c +++ b/lib/formbox.c @@ -424,34 +424,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, } else notext += *menurows; - /* cols autosize, rows autosize, rows fullscreen, menu particularity */ - if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) { - if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, - &htext, &wtext) != 0) - return (BSDDIALOG_ERROR); - } + if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext, + &wtext) != 0) + return (BSDDIALOG_ERROR); if (cols == BSDDIALOG_AUTOSIZE) *w = widget_min_width(conf, wtext, linelen + 4, &bs); if (rows == BSDDIALOG_AUTOSIZE) { - if (*menurows == 0) { + if (*menurows == BSDDIALOG_AUTOSIZE) { menusize = widget_max_height(conf) - HBORDERS - 2 /*buttons*/ - htext; menusize = MIN(menusize, nitems + 2); *menurows = menusize - 2 < 0 ? 0 : menusize - 2; - } - else /* h autosize with fixed menurows */ + } else /* h autosize with fixed menurows */ menusize = *menurows + 2; *h = widget_min_height(conf, htext, menusize, true); - /* - * avoid menurows overflow and - * with rows=AUTOSIZE menurows!=0 becomes max-menurows - */ - *menurows = MIN(*h - 6 - htext, (int)*menurows); - } else { - if (*menurows == 0) { + } else { /* fixed rows */ + if (*menurows == BSDDIALOG_AUTOSIZE) { if (*h - 6 - htext <= 0) *menurows = 0; /* form_checksize() will check */ else @@ -459,6 +450,12 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, } } + /* avoid menurows overflow and menurows becomes at most menurows */ + if (*h - 6 - htext <= 0) + *menurows = 0; /* form_checksize() will check */ + else + *menurows = MIN(*h - 6 - htext, (int)*menurows); + return (0); } diff --git a/lib/lib_util.c b/lib/lib_util.c index fcdf4c3d8769..d8c0f1d21b42 100644 --- a/lib/lib_util.c +++ b/lib/lib_util.c @@ -921,11 +921,8 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w) *h = maxheight; else if (rows < BSDDIALOG_FULLSCREEN) RETURN_ERROR("Negative (less than -1) height"); - else if (rows > BSDDIALOG_AUTOSIZE) { - if ((*h = rows) > maxheight) - RETURN_ERROR("Height too big (> terminal height - " - "shadow)"); - } + else if (rows > BSDDIALOG_AUTOSIZE) /* fixed rows */ + *h = MIN(rows, maxheight); /* rows is at most maxheight */ /* rows == AUTOSIZE: each widget has to set its size */ if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR) @@ -935,11 +932,8 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w) *w = maxwidth; else if (cols < BSDDIALOG_FULLSCREEN) RETURN_ERROR("Negative (less than -1) width"); - else if (cols > BSDDIALOG_AUTOSIZE) { - if ((*w = cols) > maxwidth) - RETURN_ERROR("Width too big (> terminal width - " - "shadow)"); - } + else if (cols > BSDDIALOG_AUTOSIZE) /* fixed cols */ + *w = MIN(cols, maxwidth); /* cols is at most maxwidth */ /* cols == AUTOSIZE: each widget has to set its size */ return (0); diff --git a/lib/lib_util.h b/lib/lib_util.h index 238d3fda4675..17ea0e0d1368 100644 --- a/lib/lib_util.h +++ b/lib/lib_util.h @@ -43,6 +43,9 @@ extern bool hastermcolors; refresh(); \ } while (0) +/* date */ +#define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) + /* unicode */ unsigned int strcols(const char *mbstring); int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col); diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c index 1a8188b0e7d3..73c1f5c2dd57 100644 --- a/lib/libbsddialog.c +++ b/lib/libbsddialog.c @@ -99,7 +99,9 @@ int bsddialog_end(void) int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle) { - mvaddstr(0, 1, backtitle); + move(0, 1); + clrtoeol(); + addstr(backtitle); if (conf->no_lines != true) mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE, SCREENCOLS - 2); diff --git a/lib/menubox.c b/lib/menubox.c index 28b9c8a0923b..bd06a9e37df2 100644 --- a/lib/menubox.c +++ b/lib/menubox.c @@ -36,7 +36,6 @@ #include "bsddialog_theme.h" #include "lib_util.h" -#define DEPTH 2 #define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */ enum menumode { @@ -277,7 +276,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y, colorname = focus ? t.menu.f_namecolor : t.menu.namecolor; if (conf->menu.no_name == false) { wattron(pad, colorname); - mvwaddstr(pad, y, pos.xname + item->depth * DEPTH, item->name); + mvwaddstr(pad, y, pos.xname + item->depth, item->name); wattroff(pad, colorname); } @@ -290,8 +289,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y, if (conf->menu.no_desc == false) { wattron(pad, colordesc); if (conf->menu.no_name) - mvwaddstr(pad, y, pos.xname + item->depth * DEPTH, - item->desc); + mvwaddstr(pad, y, pos.xname + item->depth, item->desc); else mvwaddstr(pad, y, pos.xdesc, item->desc); wattroff(pad, colordesc); @@ -307,7 +305,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y, mbtowc(&shortcut, item->desc, MB_CUR_MAX); else mbtowc(&shortcut, item->name, MB_CUR_MAX); - mvwaddwch(pad, y, pos.xname + item->depth * DEPTH, shortcut); + mvwaddwch(pad, y, pos.xname + item->depth, shortcut); wattroff(pad, colorshortcut); } @@ -362,34 +360,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, } else notext += *menurows; - /* cols autosize, rows autosize, rows fullscreen, menu particularity */ - if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) { - if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, - &htext, &wtext) != 0) - return (BSDDIALOG_ERROR); - } + if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext, + &wtext) != 0) + return (BSDDIALOG_ERROR); if (cols == BSDDIALOG_AUTOSIZE) *w = widget_min_width(conf, wtext, linelen + 4, &bs); if (rows == BSDDIALOG_AUTOSIZE) { - if (*menurows == 0) { + if (*menurows == BSDDIALOG_AUTOSIZE) { menusize = widget_max_height(conf) - HBORDERS - 2 /*buttons*/ - htext; menusize = MIN(menusize, nitems + 2); *menurows = menusize - 2 < 0 ? 0 : menusize - 2; - } - else /* h autosize with fixed menurows */ + } else /* h autosize with fixed menurows */ menusize = *menurows + 2; *h = widget_min_height(conf, htext, menusize, true); - /* - * avoid menurows overflow and - * with rows=AUTOSIZE menurows!=0 becomes max-menurows - */ - *menurows = MIN(*h - 6 - htext, (int)*menurows); - } else { - if (*menurows == 0) { + } else { /* fixed rows */ + if (*menurows == BSDDIALOG_AUTOSIZE) { if (*h - 6 - htext <= 0) *menurows = 0; /* menu_checksize() will check */ else @@ -397,6 +386,12 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, } } + /* avoid menurows overflow and menurows becomes at most menurows */ + if (*h - 6 - htext <= 0) + *menurows = 0; /* menu_checksize() will check */ + else + *menurows = MIN(*h - 6 - htext, (int)*menurows); + return (0); } @@ -475,7 +470,6 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols, } pos.maxname = conf->menu.no_name ? 0 : pos.maxname; pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc; - pos.maxdepth = DEPTH * pos.maxdepth; pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0); pos.xname = pos.xselector + pos.selectorlen + @@ -696,11 +690,15 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols, movefocus = next != abs; break; case ' ': /* Space */ - if (pritems[abs].type == MENUMODE) - break; - else if (pritems[abs].type == CHECKLISTMODE) + if (pritems[abs].type == MENUMODE) { + retval = bs.value[bs.curr]; + pritems[abs].on = true; + set_on_output(conf, retval, ngroups, groups, + pritems); + loop = false; + } else if (pritems[abs].type == CHECKLISTMODE) { pritems[abs].on = !pritems[abs].on; - else { /* RADIOLISTMODE */ + } else { /* RADIOLISTMODE */ for (i = abs - pritems[abs].index; i < totnitems && pritems[i].group == pritems[abs].group; diff --git a/lib/messagebox.c b/lib/messagebox.c index 06753be20c3d..7063ea9d273e 100644 --- a/lib/messagebox.c +++ b/lib/messagebox.c @@ -103,7 +103,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols, struct buttons bs) { bool hastext, loop; - int y, x, h, w, retval, ytextpad, htextpad, unused; + int y, x, h, w, retval, ytextpad, htextpad, printrows, unused; WINDOW *widget, *textpad, *shadow; wint_t input; @@ -120,12 +120,13 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols, true) != 0) return (BSDDIALOG_ERROR); + printrows = h - 4; ytextpad = 0; getmaxyx(textpad, htextpad, unused); unused++; /* fix unused error */ - textupdate(widget, textpad, htextpad, ytextpad, hastext); loop = true; while (loop) { + textupdate(widget, textpad, htextpad, ytextpad, hastext); doupdate(); if (get_wch(&input) == ERR) continue; @@ -160,6 +161,30 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols, wnoutrefresh(widget); } break; + case KEY_UP: + if (ytextpad > 0) + ytextpad--; + break; + case KEY_DOWN: + if (ytextpad + printrows < htextpad) + ytextpad++; + break; + case KEY_HOME: + ytextpad = 0; + break; + case KEY_END: + ytextpad = htextpad - printrows; + ytextpad = ytextpad < 0 ? 0 : ytextpad; + break; + case KEY_PPAGE: + ytextpad -= printrows; + ytextpad = ytextpad < 0 ? 0 : ytextpad; + break; + case KEY_NPAGE: + ytextpad += printrows; + if (ytextpad + printrows > htextpad) + ytextpad = htextpad - printrows; + break; case KEY_F(1): if (conf->key.f1_file == NULL && conf->key.f1_message == NULL) @@ -186,6 +211,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols, textpad, text, &bs, true) != 0) return (BSDDIALOG_ERROR); + printrows = h - 4; getmaxyx(textpad, htextpad, unused); ytextpad = 0; textupdate(widget, textpad, htextpad, ytextpad, hastext); @@ -193,18 +219,6 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols, /* Important to fix grey lines expanding screen */ refresh(); break; - case KEY_UP: - if (ytextpad == 0) - break; - ytextpad--; - textupdate(widget, textpad, htextpad, ytextpad, hastext); - break; - case KEY_DOWN: - if (ytextpad + h - 4 >= htextpad) - break; - ytextpad++; - textupdate(widget, textpad, htextpad, ytextpad, hastext); - break; default: if (shortcut_buttons(input, &bs)) { retval = bs.value[bs.curr]; diff --git a/lib/theme.c b/lib/theme.c index 40310d58cda4..6e53eb356825 100644 --- a/lib/theme.c +++ b/lib/theme.c @@ -258,7 +258,6 @@ int bsddialog_set_theme(struct bsddialog_theme *theme) int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) { - if (newtheme == BSDDIALOG_THEME_FLAT) { bsddialog_set_theme(&dialogtheme); t.dialog.lineraisecolor = t.dialog.linelowercolor; diff --git a/lib/timebox.c b/lib/timebox.c index 529563b49bca..53989bb97157 100644 --- a/lib/timebox.c +++ b/lib/timebox.c @@ -39,7 +39,7 @@ #define MINWTIME 14 /* 3 windows and their borders */ static void -drawquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt, +drawsquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt, const void *value, bool focus) { int h, l, w; @@ -167,7 +167,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows, loop = focusbuttons = true; while (loop) { for (i = 0; i < 3; i++) - drawquare(conf, c[i].win, "%02d", &c[i].value, + drawsquare(conf, c[i].win, "%02d", &c[i].value, sel == i); if (get_wch(&input) == ERR) @@ -341,8 +341,6 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, { "October", 31 }, { "November", 30 }, { "December", 31 } }; -#define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) - for (i = 0 ; i < 3; i++) { if (c[i].value > c[i].max) c[i].value = c[i].max; @@ -350,7 +348,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, c[i].value = 1; } c[2].max = m[c[1].value -1].days; - if (c[1].value == 2 && ISLEAF(c[0].value)) + if (c[1].value == 2 && ISLEAP(c[0].value)) c[2].max = 29; if (c[2].value > c[2].max) c[2].value = c[2].max; @@ -385,10 +383,10 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, sel = -1; loop = focusbuttons = true; while (loop) { - drawquare(conf, c[0].win, "%4d", &c[0].value, sel == 0); - drawquare(conf, c[1].win, "%9s", m[c[1].value-1].name, + drawsquare(conf, c[0].win, "%4d", &c[0].value, sel == 0); + drawsquare(conf, c[1].win, "%9s", m[c[1].value-1].name, sel == 1); - drawquare(conf, c[2].win, "%02d", &c[2].value, sel == 2); + drawsquare(conf, c[2].win, "%02d", &c[2].value, sel == 2); if (get_wch(&input) == ERR) continue; @@ -456,7 +454,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, /* if mount change */ c[2].max = m[c[1].value -1].days; /* if year change */ - if (c[1].value == 2 && ISLEAF(c[0].value)) + if (c[1].value == 2 && ISLEAP(c[0].value)) c[2].max = 29; /* set new day */ if (c[2].value > c[2].max) @@ -471,7 +469,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, /* if mount change */ c[2].max = m[c[1].value -1].days; /* if year change */ - if (c[1].value == 2 && ISLEAF(c[0].value)) + if (c[1].value == 2 && ISLEAP(c[0].value)) c[2].max = 29; /* set new day */ if (c[2].value > c[2].max) @@ -539,4 +537,4 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, end_dialog(conf, shadow, widget, textpad); return (retval); -} +}
\ No newline at end of file |
