contrib/bsddialog: Import version 1.0.2

Implicitly import also 1.0.1, both versions are for fixing and
feature requests.

Fixing:
Change --mixedform behavior to fix a bsdinstall fault avoiding
to change the command line in wlanconfig.

Feature requests:
 * Add keys to navigate menus.
 * Add key to redraw dialogs.
 * Avoid to handle env NCURSES_NO_UTF8_ACS in PuTTY.

See '2024-04-11 Version 1.0.2' and '2023-11-16 Version 1.0.1' in
/usr/src/contrib/bsddialog/CHANGELOG for more detailed information.

PR:			274472
Differential Revision:	D42380
vendor/bsddialog vendor/bsddialog/1.0.2
Alfonso S. Siciliano 2024-05-16 15:24:49 +02:00
parent e56a937c3e
commit be8846bd9e
No known key found for this signature in database
GPG Key ID: 3F9EEFACFD371E37
22 changed files with 470 additions and 225 deletions

View File

@ -1,3 +1,35 @@
2024-04-11 Version 1.0.2
Utility:
improvements and changes for --form and --mixedform:
* add: <maxletters> 0 sets <maxletters> like <fieldlen>.
* add: <fieldlen> 0 sets <fieldlen> like <init> width and readonly.
* change: <maxletters> 0 was an error (remains error in lib).
* change: <fieldlen> 0 was an error (remains error in lib)
(<fieldlen> 0 and <init> "" is still an error.).
Library and implicitly utility:
* add: Ctrl-l to redraw dialog.
Request stable@freebsd.org January 2024.
* add: -, +, Ctrl-p, Ctrl-n for several dialogs.
+, - request for menus, private feature request.
Ctrl-p, Ctrl-n for menu, request hackers@freebsd.org February 2024.
* fix: escaped text ending with an escape symbol.
* change: truncate mixedgauge long (over the screen/minibars)
minilabels adding "...". As a result, avoid check-size error.
https://gitlab.com/alfix/bsddialog/-/issues/6.
* change: invert UP/DOWN keys to set a rangebox value.
2023-11-16 Version 1.0.1
Library Internal Refactoring:
* add: arrow macro handlers.
* change: Box-drawing characters, from utf8 to wide chars to avoid to
handle "env NCURSES_NO_UTF8_ACS=1".
Request https://bugs.freebsd.org/274472,
Rationale https://reviews.freebsd.org/D42380.
2023-08-01 Version 1.0
Utility:

View File

@ -1,6 +1,6 @@
BSD 2-Clause License
Copyright (c) 2021-2023, Alfonso Sabato Siciliano
Copyright (c) 2021-2024, Alfonso Sabato Siciliano
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

View File

@ -3,8 +3,8 @@
#
# Written in 2023 by Alfonso Sabato Siciliano
OUTPUT = bsddialog
export VERSION=1.0
OUTPUT = bsddialog
export VERSION=1.0.2
.CURDIR ?= ${CURDIR}
LIBPATH = ${.CURDIR}/lib
LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so
@ -13,14 +13,14 @@ UTILITYPATH = ${.CURDIR}/utility
RM= rm -f
LN = ln -s -f
### cli options ###
# port/pkg Makefile: 'MAKE_ARGS = -DNORPATH'
### command-line options ###
# FreeBSD port Makefile: 'MAKE_ARGS = -DNORPATH'
NORPATH ?=
export DISABLERPATH=${NORPATH}
# `make -DDEBUG`
# `gmake DEBUG=1`
# Debug: `make -DDEBUG` or `gmake DEBUG=1`
DEBUG ?=
export ENABLEDEBUG=${DEBUG}
###################
all : ${OUTPUT}

View File

@ -1,4 +1,4 @@
# BSDDialog 1.0
# BSDDialog 1.0.2
This project provides **bsddialog** and **libbsddialog**, an utility
and a library to build scripts and tools with TUI dialogs and widgets.
@ -114,18 +114,27 @@ in the _Public Domain_ to build new projects:
## TODO and Ideas
- menubar feature
- key callback
- Right-To-Left text
- menubar feature.
- key callback.
- Right-To-Left text.
- some terminal does not hide the cursor, move it bottom-right before to getch.
- refactor backtitle: multiline, conf.backtitle, WINDOW \*dialog.backtitle.
- refactor bottomdesc: WINDOW \*dialog.bottomdesc -> fix expandig screen.
- accessibility https://wiki.freebsd.org/Accessibility/Wishlist/Base
- refactor backtitle: add WINDOW \*dialog.backtitle for multiline and fix expanding screen.
- refactor bottomdesc: add WINDOW \*dialog.bottomdesc to fix expandig screen.
- accessibility https://wiki.freebsd.org/Accessibility/Wishlist/Base.
- add bool conf.menu.depthlines.
- implement custom getopt\_long().
- refactor/redesign gauge().
- improve grey lines expanding terminal (maybe redrawwin() in hide\_dialog()).
- more restrictive strtol() and strtoul().
- implement global buttons handler.
- add/move external tutorial.
- implement menutype.min_on.
- doc: external tutorial, theming guide.
- implement menutype.min\_on.
- improve refresh at startup, avoid dialog refresh before drawing text.
- add debug API: bsddialog\_debug(y,x,refresh,"fmt",...).
- add mouse support.
- use alarm(2) for bsddialog\_pause.
- delete form fieldlen constraint, hide or truncate long field in little screens.
- improve --inputbox autosizing, consider also input length.
- fix --form "" 0 0 0 Label 1 0 Init 1 12 0 0 (with 0 editable field).
- fix --mixedform "" 0 0 0 Label 1 0 Init 1 12 0 0 2 (with 0 editable field).
- add *text* customization to --hmsg *help-message*

View File

@ -50,7 +50,7 @@ int main()
conf.title = "gauge";
rv = bsddialog_gauge(&conf, "Example", 7, 30, 0, fd[0], "SEP", "EOF");
bsddialog_end();
if(rv == BSDDIALOG_ERROR)
if (rv == BSDDIALOG_ERROR)
printf("Error: %s\n", bsddialog_geterror());
return (0);

View File

@ -69,7 +69,7 @@ int main()
minipercs[12] = i * 10;
retval= bsddialog_mixedgauge(&conf, "Example", 20, 40,
50 + i * 5, NMINIBAR, minilabels, minipercs);
if(retval == BSDDIALOG_ERROR)
if (retval == BSDDIALOG_ERROR)
exit_error();
sleep(1);
}

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -36,11 +36,11 @@
#include "bsddialog_theme.h"
#include "lib_util.h"
#define BARPADDING 2 /* widget border | BARPADDING | box bar */
#define BARPADDING 2 /* Dialog border | BARPADDING | box bar */
#define BOXBORDERS 2
#define MIN_WBAR 15
#define MIN_WBOX (BARPADDING + BOXBORDERS + MIN_WBAR + BARPADDING)
#define MIN_WMGBAR 18
#define MIN_WMGBAR 18 /* Mixedgauge main bar */
#define MIN_WMGBOX (BARPADDING + BOXBORDERS + MIN_WMGBAR + BARPADDING)
#define HBOX 3
#define WBOX(d) ((d)->w - BORDERS - BARPADDING - BARPADDING)
@ -206,12 +206,64 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
}
/* Mixedgauge */
static void
mvwaddcstr(WINDOW *win, int y, int x, const char *mbstring, unsigned int cols)
{
size_t charlen, n, w;
mbstate_t mbs;
const char *pmbstring;
wchar_t wch;
w = n = 0;
pmbstring = mbstring;
memset(&mbs, 0, sizeof(mbs));
while ((charlen = mbrlen(pmbstring, MB_CUR_MAX, &mbs)) != 0 &&
charlen != (size_t)-1 && charlen != (size_t)-2) {
mbtowc(&wch, pmbstring, charlen);
w += (wch == L'\t') ? TABSIZE : wcwidth(wch);
if (w > cols)
break;
pmbstring += charlen;
n += charlen;
}
mvwaddnstr(win, y, x, mbstring, n);
if(w > cols)
mvwaddstr(win, y, (x + cols) - 3, "...");
}
static int
mixedgauge_size_position(struct dialog *d, int nminibars,
const char **minilabels, int *htext)
{
int i, max_minibarlen;
max_minibarlen = 0;
for (i = 0; i < (int)nminibars; i++)
max_minibarlen = MAX(max_minibarlen,
(int)strcols(CHECK_STR(minilabels[i])));
max_minibarlen += 18; /* ' '<max_minibarlen>' ['13'] ' */
max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0)
return (BSDDIALOG_ERROR);
if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w,
d->text, htext, &d->bs, nminibars + HBOX, max_minibarlen) != 0)
return (BSDDIALOG_ERROR);
if (widget_checksize(d->h, d->w, &d->bs, nminibars + HBOX,
MIN_WMGBOX) != 0)
return (BSDDIALOG_ERROR);
if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0)
return (BSDDIALOG_ERROR);
return (0);
}
static int
do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
unsigned int mainperc, unsigned int nminibars, const char **minilabels,
int *minipercs, bool color)
{
int i, miniperc, max_minibarlen;
int i, miniperc;
int ystext, htext;
int minicolor, red, green;
struct bar b;
@ -223,17 +275,9 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
red = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED, BSDDIALOG_BOLD);
green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
max_minibarlen = 0;
for (i = 0; i < (int)nminibars; i++)
max_minibarlen = MAX(max_minibarlen,
(int)strcols(CHECK_STR(minilabels[i])));
max_minibarlen += 3 + 16; /* seps + [...] */
max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
return (BSDDIALOG_ERROR);
if (dialog_size_position(&d, nminibars + HBOX, max_minibarlen,
&htext) != 0)
if (mixedgauge_size_position(&d, nminibars, minilabels, &htext) != 0)
return (BSDDIALOG_ERROR);
if (draw_dialog(&d) != 0)
return (BSDDIALOG_ERROR);
@ -249,7 +293,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
/* label */
if (color && miniperc >= 0)
wattron(d.widget, A_BOLD);
mvwaddstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]));
mvwaddcstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]), d.w-20);
if (color && miniperc >= 0)
wattroff(d.widget, A_BOLD);
/* perc */
@ -472,10 +516,12 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
}
break;
case '\t': /* TAB */
case KEY_CTRL('n'):
case KEY_RIGHT:
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
DRAW_BUTTONS(d);
break;
case KEY_CTRL('p'):
case KEY_LEFT:
d.bs.curr--;
if (d.bs.curr < 0)
@ -502,15 +548,17 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
currvalue = max;
b.toupdate = true;
break;
case '-':
case KEY_UP:
if (currvalue < max) {
currvalue++;
if (currvalue > min) {
currvalue--;
b.toupdate = true;
}
break;
case '+':
case KEY_DOWN:
if (currvalue > min) {
currvalue--;
if (currvalue < max) {
currvalue++;
b.toupdate = true;
}
break;
@ -523,6 +571,7 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
if (rangebox_redraw(&d, &b, &bigchange) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (rangebox_redraw(&d, &b, &bigchange) != 0)
return (BSDDIALOG_ERROR);
@ -641,6 +690,7 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
if (pause_redraw(&d, &b) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (pause_redraw(&d, &b) != 0)
return (BSDDIALOG_ERROR);

View File

@ -1,5 +1,5 @@
.\"
.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
.\" Copyright (c) 2021-2024 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd July 28, 2023
.Dd March 16, 2024
.Dt BSDDIALOG 3
.Os
.Sh NAME
@ -719,9 +719,8 @@ the loop ends reading
builds a dialog without buttons and returns instantly.
.Pp
.Fn bsddialog_menu
builds a dialog to select an item from a list via SPACE or ENTER.
An item is
defined like:
builds a dialog to select an item from a list via SPACE and ENTER.
An item is defined like:
.Pp
.Bd -literal -offset indent -compact
struct bsddialog_menuitem {
@ -878,14 +877,13 @@ and
.Fa max .
.Fa value
is the default value on startup and the selected value at exit.
The current value is printed inside a bar, the keys UP, DOWN, HOME, END, PAGEUP
and PAGEDOWN can change it.
The current value is printed inside a bar.
.Pp
.Fn bsddialog_textbox
opens and prints
.Fa file .
UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
navigate the file, TAB changes button.
TAB key changes button.
Extra keys 0, h, l, k, j are available to navigate the text.
.Dq OK
button is renamed
.Dq EXIT .
@ -901,7 +899,24 @@ are default values on startup, selected time at exit.
.Fn bsddialog_yesno
provides a dialog for a
.Dq Yes-No Question ,
the labels on buttons are Yes and No.
the labels on buttons are
.Dq Yes
and
.Dq No .
.Ss Keys
.Bl -tag -width Ds
.It Ctrl-l
Redraw the dialog.
.It F1
Refer to
.Fa conf.key.f1_file
and
.Fa conf.key.f1_message .
.It SPACE
Select menu item.
.It UP DOWN LEFT RIGHT - + HOME END PAGEUP PAGEDOWN Ctrl-p Ctrl-n TAB
Navigate elements and set value, depending on the dialog.
.El
.Ss Theme
The graphical properties are global to the library.
They are represented by
@ -1089,7 +1104,7 @@ case BSDDIALOG_YES:
printf("Yes\\n");
break;
case BSDDIALOG_NO
printf("NO\\n");
printf("No\\n");
break;
case BSDDIALOG_ERROR:
printf("Error: %s\\n", bsddialog_geterror());

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
#include <stdbool.h>
#define LIBBSDDIALOG_VERSION "1.0"
#define LIBBSDDIALOG_VERSION "1.0.2"
/* Return values */
#define BSDDIALOG_ERROR -1

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022-2023 Alfonso Sabato Siciliano
* Copyright (c) 2022-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -120,7 +120,7 @@ init_date(unsigned int *year, unsigned int *month, unsigned int *day, int *yy,
if (*mm == 0)
*mm = 1;
*dd = (*day == 0) ? 1 : *day;
if(*dd > month_days(*yy, *mm))
if (*dd > month_days(*yy, *mm))
*dd = month_days(*yy, *mm);
}
@ -237,10 +237,8 @@ drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev,
if (focus) {
l = 2 + w%2;
wattron(win, t.dialog.arrowcolor);
mvwhline(win, 0, w/2 - l/2,
conf->ascii_lines ? '^' : ACS_UARROW, l);
mvwhline(win, h-1, w/2 - l/2,
conf->ascii_lines ? 'v' : ACS_DARROW, l);
mvwhline(win, 0, w/2 - l/2, UARROW(conf), l);
mvwhline(win, h-1, w/2 - l/2, DARROW(conf), l);
wattroff(win, t.dialog.arrowcolor);
}
@ -267,10 +265,10 @@ print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd,
draw_borders(conf, win, 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);
mvwhline(win, 0, 15, UARROW(conf), 4);
mvwhline(win, h-1, 15, DARROW(conf), 4);
mvwvline(win, 3, 0, LARROW(conf), 3);
mvwvline(win, 3, w-1, RARROW(conf), 3);
wattroff(win, t.dialog.arrowcolor);
}
@ -402,6 +400,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
case KEY_CTRL('n'):
case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
@ -418,6 +417,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@ -463,6 +463,28 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
datectl(DOWN_DAY, &yy, &mm, &dd);
}
break;
case '-':
if (focusbuttons) {
break;
} else if (sel == 0) {
datectl(UP_MONTH, &yy, &mm, &dd);
} else if (sel == 1) {
datectl(UP_YEAR, &yy, &mm, &dd);
} else { /* sel = 2 */
datectl(LEFT_DAY, &yy, &mm, &dd);
}
break;
case '+':
if (focusbuttons) {
break;
} else if (sel == 0) {
datectl(DOWN_MONTH, &yy, &mm, &dd);
} else if (sel == 1) {
datectl(DOWN_YEAR, &yy, &mm, &dd);
} else { /* sel = 2 */
datectl(RIGHT_DAY, &yy, &mm, &dd);
}
break;
case KEY_HOME:
datectl(UP_MONTH, &yy, &mm, &dd);
break;
@ -484,6 +506,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
return (BSDDIALOG_ERROR);
@ -628,8 +651,9 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
loop = false;
}
break;
case KEY_RIGHT:
case '\t': /* TAB */
case KEY_CTRL('n'):
case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
@ -648,6 +672,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@ -665,6 +690,10 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
case '-':
if (focusbuttons == false)
datectl(di[sel].up, &yy, &mm, &dd);
break;
case KEY_UP:
if (focusbuttons) {
sel = 0;
@ -675,6 +704,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
datectl(di[sel].up, &yy, &mm, &dd);
}
break;
case '+':
case KEY_DOWN:
if (focusbuttons)
break;
@ -689,6 +719,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
if (datebox_redraw(&d, di) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (datebox_redraw(&d, di) != 0)
return (BSDDIALOG_ERROR);

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -82,7 +82,7 @@ struct privateform {
unsigned int viewrows; /* visible rows, real formheight */
unsigned int minviewrows; /* min viewrows, ylabel != yfield */
wchar_t securewch; /* wide char of conf.form.secure[mb]ch */
unsigned int nitems; /* like API nkitems */
unsigned int nitems; /* like API nitems */
struct privateitem *pritems;
int sel; /* selected item in pritem, can be -1 */
bool hasbottomdesc; /* some item has bottomdesc */
@ -101,12 +101,12 @@ build_privateform(struct bsddialog_conf*conf, unsigned int nitems,
/* checks */
CHECK_ARRAY(nitems, items);
for (i = 0; i < nitems; i++) {
if (items[i].maxvaluelen == 0)
RETURN_FMTERROR("item %u [0-%u] maxvaluelen = 0",
i, nitems);
if (items[i].fieldlen == 0)
RETURN_FMTERROR("item %u [0-%u] fieldlen = 0",
i, nitems);
if (items[i].maxvaluelen == 0)
RETURN_FMTERROR("item %u [0-%u] maxvaluelen = 0",
i, nitems);
}
f->nitems = nitems;
@ -114,7 +114,7 @@ build_privateform(struct bsddialog_conf*conf, unsigned int nitems,
insecurecursor = false;
if (conf->form.securembch != NULL) {
mbchsize = mblen(conf->form.securembch, MB_LEN_MAX);
if(mbtowc(&f->securewch, conf->form.securembch, mbchsize) < 0)
if (mbtowc(&f->securewch, conf->form.securembch, mbchsize) < 0)
RETURN_ERROR("Cannot convert securembch to wchar_t");
insecurecursor = true;
} else if (conf->form.securech != '\0') {
@ -346,7 +346,7 @@ static char* alloc_wstomb(wchar_t *wstr)
wctomb(mbch, wstr[i]);
nbytes += mblen(mbch, MB_LEN_MAX);
}
if((mbstr = malloc(nbytes)) == NULL)
if ((mbstr = malloc(nbytes)) == NULL)
return (NULL);
wcstombs(mbstr, wstr, nbytes);
@ -379,7 +379,7 @@ static void set_first_with_default(struct privateform *f, int *focusitem)
unsigned int i;
f->sel = -1;
if(focusitem != NULL && *focusitem >=0 && *focusitem < (int)f->nitems)
if (focusitem != NULL && *focusitem >=0 && *focusitem < (int)f->nitems)
if (f->pritems[*focusitem].readonly == false) {
f->sel = *focusitem;
return;
@ -535,12 +535,10 @@ static void update_formbox(struct bsddialog_conf *conf, struct privateform *f)
if (f->viewrows < f->h) {
wattron(f->box, t.dialog.arrowcolor);
if (f->y > 0)
mvwhline(f->box, 0, (w / 2) - 2,
conf->ascii_lines ? '^' : ACS_UARROW, 5);
mvwhline(f->box, 0, (w / 2) - 2, UARROW(conf), 5);
if (f->y + f->viewrows < f->h)
mvwhline(f->box, h-1, (w / 2) - 2,
conf->ascii_lines ? 'v' : ACS_DARROW, 5);
mvwhline(f->box, h-1, (w / 2) - 2, DARROW(conf), 5);
wattroff(f->box, t.dialog.arrowcolor);
}
}
@ -750,7 +748,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
break;
case KEY_LEFT:
if (focusinform) {
if(fieldctl(item, MOVE_CURSOR_LEFT))
if (fieldctl(item, MOVE_CURSOR_LEFT))
DRAWITEM_TRICK(&form, form.sel, true);
} else if (d.bs.curr > 0) {
d.bs.curr--;
@ -762,7 +760,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
break;
case KEY_RIGHT:
if (focusinform) {
if(fieldctl(item, MOVE_CURSOR_RIGHT))
if (fieldctl(item, MOVE_CURSOR_RIGHT))
DRAWITEM_TRICK(&form, form.sel, true);
} else if (d.bs.curr < (int) d.bs.nbuttons - 1) {
d.bs.curr++;
@ -772,6 +770,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
switchfocus = true;
}
break;
case KEY_CTRL('p'):
case KEY_UP:
if (focusinform) {
next = previtem(form.nitems, form.pritems,
@ -781,6 +780,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
switchfocus = true;
}
break;
case KEY_CTRL('n'):
case KEY_DOWN:
if (focusinform == false)
break;
@ -808,20 +808,20 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
case 127: /* Backspace */
if (focusinform == false)
break;
if(fieldctl(item, MOVE_CURSOR_LEFT))
if(fieldctl(item, DEL_LETTER))
if (fieldctl(item, MOVE_CURSOR_LEFT))
if (fieldctl(item, DEL_LETTER))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_DC:
if (focusinform == false)
break;
if(fieldctl(item, DEL_LETTER))
if (fieldctl(item, DEL_LETTER))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_HOME:
if (focusinform == false)
break;
if(fieldctl(item, MOVE_CURSOR_BEGIN))
if (fieldctl(item, MOVE_CURSOR_BEGIN))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_END:
@ -842,6 +842,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
if (form_redraw(&d, &form, focusinform) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (form_redraw(&d, &form, focusinform) != 0)
return (BSDDIALOG_ERROR);
@ -857,10 +858,10 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
* because the cursor remains on the new letter,
* "if" and "while" update the positions.
*/
if(insertch(item, input, form.securewch)) {
if (insertch(item, input, form.securewch)) {
fieldctl(item, MOVE_CURSOR_RIGHT);
/*
* no if(fieldctl), update always
* no if (fieldctl), update always
* because it fails with maxletters.
*/
DRAWITEM_TRICK(&form, form.sel, true);
@ -897,7 +898,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
DRAWITEM_TRICK(&form, form.sel, true);
changeitem = false;
}
} /* end while(loop) */
} /* end while (loop) */
curs_set(0);

View File

@ -983,41 +983,43 @@ void draw_borders(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev)
{
int h, w;
int leftcolor, rightcolor;
int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee;
cchar_t *ls, *rs, *ts, *bs, *tl, *tr, *bl, *br;
cchar_t hline, vline, corner;
if (conf->no_lines)
return;
if (conf->ascii_lines) {
ls = rs = '|';
ts = bs = '-';
tl = tr = bl = br = ltee = rtee = '+';
setcchar(&hline, L"|", 0, 0, NULL);
ls = rs = &hline;
setcchar(&vline, L"-", 0, 0, NULL);
ts = bs = &vline;
setcchar(&corner, L"+", 0, 0, NULL);
tl = tr = bl = br = &corner;
} else {
ls = rs = ACS_VLINE;
ts = bs = ACS_HLINE;
tl = ACS_ULCORNER;
tr = ACS_URCORNER;
bl = ACS_LLCORNER;
br = ACS_LRCORNER;
ltee = ACS_LTEE;
rtee = ACS_RTEE;
ls = rs = WACS_VLINE;
ts = bs = WACS_HLINE;
tl = WACS_ULCORNER;
tr = WACS_URCORNER;
bl = WACS_LLCORNER;
br = WACS_LRCORNER;
}
getmaxyx(win, h, w);
leftcolor = elev == RAISED ?
leftcolor = (elev == RAISED) ?
t.dialog.lineraisecolor : t.dialog.linelowercolor;
rightcolor = elev == RAISED ?
rightcolor = (elev == RAISED) ?
t.dialog.linelowercolor : t.dialog.lineraisecolor;
wattron(win, leftcolor);
wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
wborder_set(win, ls, rs, ts, bs, tl, tr, bl, br);
wattroff(win, leftcolor);
wattron(win, rightcolor);
mvwaddch(win, 0, w-1, tr);
mvwvline(win, 1, w-1, rs, h-2);
mvwaddch(win, h-1, w-1, br);
mvwhline(win, h-1, 1, bs, w-2);
mvwadd_wch(win, 0, w-1, tr);
mvwvline_set(win, 1, w-1, rs, h-2);
mvwadd_wch(win, h-1, w-1, br);
mvwhline_set(win, h-1, 1, bs, w-2);
wattroff(win, rightcolor);
}
@ -1126,30 +1128,31 @@ static void
print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
bool color)
{
int i, j, len, reallen, wc;
int charwidth, i, j, strlen, strwidth;
wchar_t ws[2];
ws[1] = L'\0';
len = wcslen(str);
strlen = wcslen(str);
if (color) {
reallen = 0;
strwidth = 0;
i=0;
while (i < len) {
while (i < strlen) {
if (is_wtext_attr(str+i) == false) {
reallen += wcwidth(str[i]);
strwidth += wcwidth(str[i]);
i++;
} else {
i +=3 ;
i += 3;
}
}
} else
reallen = wcswidth(str, len);
strwidth = wcswidth(str, strlen);
i = 0;
while (i < len) {
if (*x + reallen > cols) {
*y = (*x != 0 ? *y+1 : *y);
while (i < strlen) {
if (*x + strwidth > cols) {
if (*x != 0)
*y = *y + 1;
if (*y >= *rows) {
*rows = *y + 1;
wresize(win, *rows, cols);
@ -1157,21 +1160,22 @@ print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
*x = 0;
}
j = *x;
while (j < cols && i < len) {
while (i < strlen) {
if (color && check_set_wtext_attr(win, str+i)) {
i += 3;
} else if (j + wcwidth(str[i]) > cols) {
break;
} else {
/* inline mvwaddwch() for efficiency */
ws[0] = str[i];
mvwaddwstr(win, *y, j, ws);
wc = wcwidth(str[i]);;
reallen -= wc;
j += wc;
i++;
*x = j;
continue;
}
charwidth = wcwidth(str[i]);
if (j + wcwidth(str[i]) > cols)
break;
/* inline mvwaddwch() for efficiency */
ws[0] = str[i];
mvwaddwstr(win, *y, j, ws);
strwidth -= charwidth;
j += charwidth;
*x = j;
i++;
}
}
}
@ -1248,11 +1252,18 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
int draw_dialog(struct dialog *d)
{
int wtitle, wbottomtitle, ts, ltee, rtee;
int wtitle, wbottomtitle;
cchar_t ts, ltee, rtee;
ts = d->conf->ascii_lines ? '-' : ACS_HLINE;
ltee = d->conf->ascii_lines ? '+' : ACS_LTEE;
rtee = d->conf->ascii_lines ? '+' : ACS_RTEE;
if (d->conf->ascii_lines) {
setcchar(&ts, L"-", 0, 0, NULL);
setcchar(&ltee, L"+", 0, 0,NULL);
setcchar(&rtee, L"+", 0, 0, NULL);
} else {
ts = *WACS_HLINE;
ltee = *WACS_LTEE;
rtee = *WACS_RTEE;
}
if (d->conf->shadow) {
wclear(d->shadow);
@ -1271,7 +1282,7 @@ int draw_dialog(struct dialog *d)
return (BSDDIALOG_ERROR);
if (t.dialog.delimtitle && d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
mvwaddch(d->widget, 0, d->w/2 - wtitle/2 -1, rtee);
mvwadd_wch(d->widget, 0, d->w/2 - wtitle/2 -1, &rtee);
wattroff(d->widget, t.dialog.lineraisecolor);
}
wattron(d->widget, t.dialog.titlecolor);
@ -1279,7 +1290,7 @@ int draw_dialog(struct dialog *d)
wattroff(d->widget, t.dialog.titlecolor);
if (t.dialog.delimtitle && d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
waddch(d->widget, ltee);
wadd_wch(d->widget, &ltee);
wattroff(d->widget, t.dialog.lineraisecolor);
}
}
@ -1287,12 +1298,12 @@ int draw_dialog(struct dialog *d)
if (d->bs.nbuttons > 0) {
if (d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
mvwaddch(d->widget, d->h-3, 0, ltee);
mvwhline(d->widget, d->h-3, 1, ts, d->w-2);
mvwadd_wch(d->widget, d->h-3, 0, &ltee);
mvwhline_set(d->widget, d->h-3, 1, &ts, d->w-2);
wattroff(d->widget, t.dialog.lineraisecolor);
wattron(d->widget, t.dialog.linelowercolor);
mvwaddch(d->widget, d->h-3, d->w-1, rtee);
mvwadd_wch(d->widget, d->h-3, d->w-1, &rtee);
wattroff(d->widget, t.dialog.linelowercolor);
}
draw_buttons(d);

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -62,14 +62,19 @@ extern bool hastermcolors;
RETURN_ERROR("*" #p " is NULL"); \
} while (0)
#define CHECK_ARRAY(nitem, a) do { \
if(nitem > 0 && a == NULL) \
if (nitem > 0 && a == NULL) \
RETURN_FMTERROR(#nitem " is %d but *" #a " is NULL", nitem); \
} while (0)
/* widget utils */
#define KEY_CTRL(c) (c & 037)
#define TEXTPAD(d, downnotext) rtextpad(d, 0, 0, 0, downnotext)
#define SCREENLINES (getmaxy(stdscr))
#define SCREENCOLS (getmaxx(stdscr))
#define CHECK_STR(s) (s == NULL ? "" : s)
#define UARROW(c) (c->ascii_lines ? '^' : ACS_UARROW)
#define DARROW(c) (c->ascii_lines ? 'v' : ACS_DARROW)
#define LARROW(c) (c->ascii_lines ? '<' : ACS_LARROW)
#define RARROW(c) (c->ascii_lines ? '>' : ACS_RARROW)
#define DRAW_BUTTONS(d) do { \
draw_buttons(&d); \
wnoutrefresh(d.widget); \

View File

@ -107,9 +107,12 @@ int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
move(0, 1);
clrtoeol();
addstr(CHECK_STR(backtitle));
if (conf->no_lines != true)
mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
SCREENCOLS - 2);
if (conf->no_lines != true) {
if (conf->ascii_lines)
mvhline(1, 1, '-', SCREENCOLS - 2);
else
mvhline_set(1, 1, WACS_HLINE, SCREENCOLS - 2);
}
refresh();

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -183,7 +183,7 @@ set_return_on(struct privatemenu *m, struct bsddialog_menugroup *groups)
int i;
struct privateitem *pritem;
for(i = 0; i < m->nitems; i++) {
for (i = 0; i < m->nitems; i++) {
if (m->pritems[i].type == SEPARATORMODE)
continue;
pritem = &m->pritems[i];
@ -298,7 +298,7 @@ getnextshortcut(int npritems, struct privateitem *pritems, int abs, wint_t key)
static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m)
{
int i, linech, realw, labellen;
int i, realw, labellen;
const char *desc, *name;
for (i = 0; i < m->nitems; i++) {
@ -306,8 +306,10 @@ static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m)
continue;
if (conf->no_lines == false) {
wattron(m->pad, t.menu.desccolor);
linech = conf->ascii_lines ? '-' : ACS_HLINE;
mvwhline(m->pad, i, 0, linech, m->line);
if (conf->ascii_lines)
mvwhline(m->pad, i, 0, '-', m->line);
else
mvwhline_set(m->pad, i, 0, WACS_HLINE, m->line);
wattroff(m->pad, t.menu.desccolor);
}
name = m->pritems[i].name;
@ -404,12 +406,10 @@ static void update_menubox(struct bsddialog_conf *conf, struct privatemenu *m)
if (m->nitems > (int)m->menurows) {
wattron(m->box, t.dialog.arrowcolor);
if (m->ypad > 0)
mvwhline(m->box, 0, 2,
conf->ascii_lines ? '^' : ACS_UARROW, 3);
mvwhline(m->box, 0, 2, UARROW(conf), 3);
if ((m->ypad + (int)m->menurows) < m->nitems)
mvwhline(m->box, h-1, 2,
conf->ascii_lines ? 'v' : ACS_DARROW, 3);
mvwhline(m->box, h-1, 2, DARROW(conf), 3);
mvwprintw(m->box, h-1, w-6, "%3d%%",
100 * (m->ypad + m->menurows) / m->nitems);
@ -578,6 +578,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
if (mixedlist_redraw(&d, &m) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (mixedlist_redraw(&d, &m) != 0)
return (BSDDIALOG_ERROR);
@ -591,6 +592,8 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
next = getnext(m.nitems, m.pritems, -1);
changeitem = next != m.sel;
break;
case '-':
case KEY_CTRL('p'):
case KEY_UP:
next = getprev(m.pritems, m.sel);
changeitem = next != m.sel;
@ -603,6 +606,8 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
next = getprev(m.pritems, m.nitems);
changeitem = next != m.sel;
break;
case '+':
case KEY_CTRL('n'):
case KEY_DOWN:
next = getnext(m.nitems, m.pritems, m.sel);
changeitem = next != m.sel;
@ -665,7 +670,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe);
changeitem = false;
}
} /* end while(loop) */
} /* end while (loop) */
set_return_on(&m, groups);

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -87,7 +87,7 @@ static int message_draw(struct dialog *d, struct scroll *s)
s->printrows = d->h - BORDER - HBUTTONS - BORDER;
s->ypad = 0;
getmaxyx(d->textpad, s->htextpad, unused);
unused++; /* fix unused error */
(void)unused; /* fix unused error */
return (0);
}
@ -106,7 +106,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
return (BSDDIALOG_ERROR);
set_buttons(&d, true, oklabel, cancellabel);
s.htext = -1;
if(message_draw(&d, &s) != 0)
if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
loop = true;
@ -138,10 +138,14 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
d.bs.curr = d.bs.nbuttons - 1;
DRAW_BUTTONS(d);
break;
case '-':
case KEY_CTRL('p'):
case KEY_UP:
if (s.ypad > 0)
s.ypad--;
break;
case '+':
case KEY_CTRL('n'):
case KEY_DOWN:
if (s.ypad + s.printrows < s.htextpad)
s.ypad++;
@ -166,11 +170,12 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
break;
if (f1help_dialog(d.conf) != 0)
return (BSDDIALOG_ERROR);
if(message_draw(&d, &s) != 0)
if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if(message_draw(&d, &s) != 0)
if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
break;
default:

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -47,32 +47,33 @@ struct scrolltext {
static void updateborders(struct dialog *d, struct scrolltext *st)
{
chtype arrowch, borderch;
chtype arrowch;
cchar_t borderch;
if (d->conf->no_lines)
borderch = ' ';
setcchar(&borderch, L" ", 0, 0, NULL);
else if (d->conf->ascii_lines)
borderch = '|';
setcchar(&borderch, L"|", 0, 0, NULL);
else
borderch = ACS_VLINE;
borderch = *WACS_VLINE;
if (st->xpad > 0) {
arrowch = d->conf->ascii_lines ? '<' : ACS_LARROW;
arrowch |= t.dialog.arrowcolor;
arrowch = LARROW(d->conf) | t.dialog.arrowcolor;
mvwvline(d->widget, (d->h / 2) - 2, 0, arrowch, 4);
} else {
arrowch = borderch;
arrowch |= t.dialog.lineraisecolor;
wattron(d->widget, t.dialog.lineraisecolor);
mvwvline_set(d->widget, (d->h / 2) - 2, 0, &borderch, 4);
wattroff(d->widget, t.dialog.lineraisecolor);
}
mvwvline(d->widget, (d->h / 2) - 2, 0, arrowch, 4);
if (st->xpad + d->w - 2 - st->margin < st->wpad) {
arrowch = d->conf->ascii_lines ? '>' : ACS_RARROW;
arrowch |= t.dialog.arrowcolor;
arrowch = RARROW(d->conf) | t.dialog.arrowcolor;
mvwvline(d->widget, (d->h / 2) - 2, d->w - 1, arrowch, 4);
} else {
arrowch = borderch;
arrowch |= t.dialog.linelowercolor;
wattron(d->widget, t.dialog.linelowercolor);
mvwvline_set(d->widget, (d->h / 2) - 2, d->w - 1, &borderch, 4);
wattroff(d->widget, t.dialog.linelowercolor);
}
mvwvline(d->widget, (d->h / 2) - 2, d->w - 1, arrowch, 4);
if (st->hpad > d->h - 4) {
wattron(d->widget, t.dialog.arrowcolor);
@ -181,7 +182,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
while (loop) {
updateborders(&d, &st);
/*
* Overflow multicolumn charchter right border:
* Trick, overflow multicolumn charchter right border:
* wnoutrefresh(widget);
* pnoutrefresh(pad, ypad, xpad, ys, xs, ye, xe);
* doupdate();
@ -256,6 +257,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
if (textbox_draw(&d, &st) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (textbox_draw(&d, &st) != 0)
return (BSDDIALOG_ERROR);

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -48,8 +48,8 @@ drawsquare(struct bsddialog_conf *conf, WINDOW *win, unsigned int value,
draw_borders(conf, win, LOWERED);
if (focus) {
wattron(win, t.dialog.arrowcolor);
mvwhline(win, 0, 1, conf->ascii_lines ? '^' : ACS_UARROW, 2);
mvwhline(win, 2, 1, conf->ascii_lines ? 'v' : ACS_DARROW, 2);
mvwhline(win, 0, 1, UARROW(conf), 2);
mvwhline(win, 2, 1, DARROW(conf), 2);
wattroff(win, t.dialog.arrowcolor);
}
@ -142,8 +142,9 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
loop = false;
}
break;
case KEY_RIGHT:
case '\t': /* TAB */
case KEY_CTRL('n'):
case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
@ -162,6 +163,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
}
DRAW_BUTTONS(d);
break;
case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@ -179,6 +181,11 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
}
DRAW_BUTTONS(d);
break;
case '-':
if (focusbuttons == false)
c[sel].value = c[sel].value > 0 ?
c[sel].value - 1 : c[sel].max;
break;
case KEY_UP:
if (focusbuttons) {
sel = 0;
@ -190,6 +197,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
c[sel].value - 1 : c[sel].max;
}
break;
case '+':
case KEY_DOWN:
if (focusbuttons)
break;
@ -205,6 +213,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);

View File

@ -1,5 +1,5 @@
.\"
.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
.\" Copyright (c) 2021-2024 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd July 25, 2023
.Dd April 7, 2024
.Dt BSDDIALOG 1
.Os
.Sh NAME
@ -438,6 +438,21 @@ timeout.
.It Fl Fl title Ar title
Dialog title.
.El
.Ss Keys
The following keys are available at runtime:
.Bl -tag -width Ds
.It Ctrl-l
Redraw the dialog.
.It F1
See
.Fl Fl hfile
and
.Fl Fl hmsg .
.It SPACE
Select menu item.
.It UP DOWN LEFT RIGHT - + HOME END PAGEUP PAGEDOWN Ctrl-p Ctrl-n TAB
Navigate elements and set value, depending on the dialog.
.El
.Ss Dialogs
The following dialogs are available:
.Bl -tag -width Ds
@ -472,20 +487,21 @@ and
a field to get the input at the position
.Ar yfield
and
.Ar xfield
with graphical length
.Ar fieldlen ,
.Ar maxletters
is the maximum input length.
The field can be customized, if
.Ar xfield .
.Ar fieldlen
is negative the field is read only and its absolute value is the field length.
If
is the field width, if negative is readonly and the width is the absolute value,
if
.Dv 0
the field becomes readonly and its value is the
.Ar init
width.
.Ar maxletters
is 0 it is the absolute value of
is the maximum input length, if is
.Dv 0
its value is
.Ar fieldlen .
.Ar init
is a default value.
is the default value in the field.
.Ar formrows
is the graphical height of the list,
.Dv 0
@ -509,7 +525,7 @@ Dialog to get a string in input,
.Ar init
is the default value.
.It Fl Fl menu Ar text Ar rows Ar cols Ar menurows Oo Ar name desc Oc ...
Builds a menu to select an item from a list, Space key is equivalent to Enter.
Builds a menu to select an item from a list, SPACE key is equivalent to ENTER.
An item has a
.Ar name
and a
@ -526,19 +542,33 @@ at the position
.Ar ylabel
and
.Ar xlabel ,
a field to get the input with graphical length
.Ar fieldlen
at the position
a field to get the input at the position
.Ar yfield
and
.Ar xfield ,
.Ar maxletters
is the maximum input length,
.Ar xfield .
.Ar fieldlen
is the field width, if negative is readonly and the width is the absolute value,
if
.Dv 0
the field becomes readonly and its value is the
.Ar init
is a default value,
width.
.Ar maxletters
is the maximum input length, if is
.Dv 0
its value is
.Ar fieldlen .
.Ar init
is the default value in the field.
.Ar flag
can be 0 for normal field, 1 to hide the typed characters and 2 to set the
field read only.
can customize
.Ar field :
.Dv 0
normal,
.Dv 1
hide typed characters,
.Dv 2
readonly.
.Ar formrows
is the graphical height of the list,
.Dv 0
@ -581,7 +611,6 @@ otherwise
Dialog to diplay a message without the
.Dq Cancel
button.
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to scroll the text.
.It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init
Dialog to get a password,
.Ar init
@ -617,13 +646,12 @@ Dialog to select a value between
and
.Ar max ,
.Ar init
is the default value, the keys UP, DOWN, HOME, END, PAGEUP and PAGEDOWN can
change it.
is the default value.
.It Fl Fl textbox Ar file Ar rows Ar cols
Opens and prints
.Ar file .
UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
navigate the file, TAB changes button.
TAB changes button.
Extra keys 0, h, l, k, j are available to navigate the text.
.Dq OK
button is renamed
.Dq EXIT .
@ -644,7 +672,6 @@ buttons are renamed
.Dq Yes
and
.Dq \&No .
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to scroll the text.
.El
.Sh ENVIRONMENT
The following environment variables take effect only on startup, other options
@ -872,6 +899,8 @@ Options:
.Fl Fl version ,
.Fl Fl yes-label .
.Pp
Keys: Ctrl-l, F1.
.Pp
Dialogs:
.Fl Fl calendar ,
.Fl Fl checklist ,

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -140,7 +140,7 @@ static void getenv_exitcodes(void)
value = (int)strtol(envvalue, NULL, 10);
exitcodes[i].value = value;
/* ITEM_HELP follows HELP without explicit setting */
if(i == BSDDIALOG_HELP + 1)
if (i == BSDDIALOG_HELP + 1)
exitcodes[BSDDIALOG_ITEM_HELP + 1].value = value;
}
}
@ -242,7 +242,7 @@ int main(int argc, char *argv[argc])
if (opt.dialogbuilder == NULL)
break;
if (opt.backtitle != NULL)
if(bsddialog_backtitle(&conf, opt.backtitle))
if (bsddialog_backtitle(&conf, opt.backtitle))
exit_error(false, bsddialog_geterror());
retval = opt.dialogbuilder(&conf, text, rows, cols, argc, argv,
&opt);

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
* Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,6 +30,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <wchar.h>
#include <bsddialog.h>
#include <bsddialog_theme.h>
@ -532,6 +533,29 @@ int treeview_builder(BUILDER_ARGS)
}
/* form */
static unsigned int strcols(const char *string)
{
int w;
unsigned int ncol;
size_t charlen, mb_cur_max;
wchar_t wch;
mbstate_t mbs;
mb_cur_max = MB_CUR_MAX;
ncol = 0;
memset(&mbs, 0, sizeof(mbs));
while ((charlen = mbrlen(string, mb_cur_max, &mbs)) != 0 &&
charlen != (size_t)-1 && charlen != (size_t)-2) {
if (mbtowc(&wch, string, mb_cur_max) < 0)
return (0);
if ((w = wcwidth(wch)) > 0)
ncol += w;
string += charlen;
}
return (ncol);
}
static void
print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int focusitem, struct options *opt)
@ -551,7 +575,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
helpname = items[focusitem].bottomdesc;
dprintf(opt->output_fd, " %s", helpname);
}
if(opt->help_print_items == false)
if (opt->help_print_items == false)
return;
dprintf(opt->output_fd, "\n");
}
@ -564,7 +588,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int form_builder(BUILDER_ARGS)
{
int output, fieldlen, valuelen, focusitem;
int output, fieldlen, focusitem;
unsigned int i, j, flags, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@ -591,12 +615,16 @@ int form_builder(BUILDER_ARGS)
items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
fieldlen = (int)strtol(argv[j++], NULL, 10);
items[i].fieldlen = abs(fieldlen);
if (fieldlen == 0)
items[i].fieldlen = strcols(items[i].init);
else
items[i].fieldlen = abs(fieldlen);
valuelen = (int)strtol(argv[j++], NULL, 10);
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
if (items[i].maxvaluelen == 0)
items[i].maxvaluelen = items[i].fieldlen;
flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
flags = (fieldlen <= 0) ? BSDDIALOG_FIELDREADONLY : 0;
items[i].flags = flags;
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
@ -643,7 +671,7 @@ int inputbox_builder(BUILDER_ARGS)
int mixedform_builder(BUILDER_ARGS)
{
int output, focusitem;
int output, fieldlen, focusitem;
unsigned int i, j, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@ -662,16 +690,26 @@ int mixedform_builder(BUILDER_ARGS)
exit_error(false, "cannot allocate memory for form items");
j = 0;
for (i = 0; i < nitems; i++) {
items[i].label = argv[j++];
items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
items[i].init = argv[j++];
items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
items[i].fieldlen = (u_int)strtoul(argv[j++], NULL, 10);
items[i].label = argv[j++];
items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
items[i].init = argv[j++];
items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
fieldlen = (int)strtol(argv[j++], NULL, 10);
if (fieldlen == 0)
items[i].fieldlen = strcols(items[i].init);
else
items[i].fieldlen = abs(fieldlen);
items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
if (items[i].maxvaluelen == 0)
items[i].maxvaluelen = items[i].fieldlen;
items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
if (fieldlen <= 0)
items[i].flags |= BSDDIALOG_FIELDREADONLY;
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
}
focusitem = -1;

View File

@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022-2023 Alfonso Sabato Siciliano
* Copyright (c) 2022-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -166,7 +166,7 @@ void savetheme(const char *file)
exit_error(false,
"cannot save theme: %s", bsddialog_geterror());
if(time(&clock) < 0)
if (time(&clock) < 0)
exit_error(false, "cannot save profile getting current time");
if ((fp = fopen(file, "w")) == NULL)
exit_error(false, "cannot open %s to save profile", file);
@ -235,11 +235,11 @@ void loadtheme(const char *file, bool compatibility)
exit_error(false, "Cannot get current theme: %s",
bsddialog_geterror());
if((fp = fopen(file, "r")) == NULL)
if ((fp = fopen(file, "r")) == NULL)
exit_error(false, "Cannot open theme \"%s\" file", file);
while(fgets(line, BUFSIZ, fp) != NULL) {
if(line[0] == '#' || line[0] == '\n')
while (fgets(line, BUFSIZ, fp) != NULL) {
if (line[0] == '#' || line[0] == '\n')
continue; /* superfluous, only for efficiency */
sscanf(line, "%s", name);
value = NULL; /* useless init, fix compiler warning */
@ -322,7 +322,7 @@ void loadtheme(const char *file, bool compatibility)
fclose(fp);
if(bsddialog_set_theme(&t) != BSDDIALOG_OK)
if (bsddialog_set_theme(&t) != BSDDIALOG_OK)
exit_error(false, bsddialog_geterror());
}