contrib/bsddialog: Import version 0.4

Improvements and changes to integrate bsddialog(1) with scripts in BASE.
Overview:

 * New options. --and-widget, --keep-tite, --calendar.
 * Change output format. Menus and --print-maxsize.
 * Redefine sizing. Fixed rows, cols and menurows became at the most.
 * Add DIAGNOSTICS. Error messages for bad arguments and options.
 * Add keys. Space for --menu, fast keys for --msgbox and --yesno.
 * Text. Change default text modification, add --cr-wrap.

See /usr/src/contrib/bsddialog/CHANGELOG '2022-09-24 Version 0.4'
for more detailed information.

Merge commit '9f24fda5a8e7ab8243e71473c7e2dc98b4877e64'
This commit is contained in:
Alfonso S. Siciliano 2022-09-25 15:07:29 +02:00
commit 84823cc708
No known key found for this signature in database
GPG Key ID: 3F9EEFACFD371E37
30 changed files with 1734 additions and 847 deletions

View File

@ -1,29 +1,24 @@
bsddialog bsddialog
.depend*
*.o *.o
*~ *.so*
*.a *.a
examples_library/buildlist *.gz
*.core
*~
BSDDIALOG.geany
BSDDIALOG.tags
examples_library/calendar
examples_library/checklist examples_library/checklist
examples_library/datebox examples_library/datebox
examples_library/form examples_library/form
examples_library/formw examples_library/infobox
examples_library/margin
examples_library/menu examples_library/menu
examples_library/mixedlist examples_library/mixedlist
examples_library/radiolist
examples_library/theme
examples_library/treeview
examples_library/infobox
examples_library/msgbox examples_library/msgbox
examples_library/pause examples_library/pause
examples_library/radiolist
examples_library/rangebox examples_library/rangebox
examples_library/sade examples_library/theme
examples_library/timebox examples_library/timebox
examples_library/yesno examples_library/yesno
examples_library/u_msgbox
*.gz
lib/libbsddialog.so*
BSDDIALOG.geany
BSDDIALOG.tags
*.core
freebsd-lab/

View File

@ -1,17 +1,68 @@
2022-09-24 Version 0.4
Utility:
* add: --normal-screen to set normal mode.
* add: --alternate-screen to set alternate mode.
* add: --keep-tite as --alternate-screen alias.
* add: --and-dialog to build other dialogs.
* add: --and-widget as --and-dialog alias.
* add: --no-names (--no-tags becames its alias).
* add: --no-descriptions (--no-items becames its alias).
* add: --help-print-name (--help-tags becames its alias).
* add: --item-bottom-desc (--item-help becames its alias).
* add: --cr-wrap (was partially implemented) to keep '\n' with "\n".
* add: --text-unchanged to avoid default modification.
* add: --tab-escape enables "\t" in text.
* add: --clear-screen to clear the screen.
* add: --clear-dialog to clear the dialog (was --clear).
* add: --calendar dialog to select a date.
* add: DIAGNOSTICS messages for bad arguments number.
* add: DIAGNOSTICS messages for missing and unexpected options.
* change: --clear becames alias for --clear-screen.
* change: --print-maxsize format output.
* change: --menu, --radiolist, --checklist and --treeview output.
- no printed items with Cancel or ESC.
- --separator prints <sepstr> before each item except HELP.
- --separator and --separate-output print <sepstr> after each item.
- quoted item name/desc only when needed.
- --menu avoids to print selected item after focused HELP item.
* change: text default modification.
- without a "\n": '\t' -> space, '\n' -> '\n', trim spaces.
- with a "\n": '\t' -> space, '\n' -> space, "\n" -> '\n', no trim.
- delete '\n' after "\n" (also with --cr-wrap).
* change: --datebox input and output format yy/mm/dd -> dd/mm/yy.
* delete: --no-collapse (partially implemented).
* delete: --no-nl-expand (partially implemented).
* delete: --trim (partially implemented).
Library:
* add: bsddialog_msgbox() HOME, END, PPAGE and NPAGE keys.
* add: bsddialog_yesno() HOME, END, PPAGE and NPAGE keys.
* add: bsddialog_menu() SPACE key (equivalent to ENTER).
* add: bsddialog_calendar() to select a date.
* change: rename enum bsddialog_grouptype -> enum bsddialog_menutype.
* change: fixed-menurows becames at most menurows (depending on text).
* change: fixed-rows becames at most rows, min(rows, screenH - shadow).
* change: fixed-cols becames at most cols, min(cols, screenW - shadow).
* delete: undocumented internal bsddialog_menuitem.depth factor (was 2).
2022-08-29 Version 0.3 2022-08-29 Version 0.3
Utility: Utility:
* add: --textbox accepts options for the first button. * add: --textbox accepts options for the first button.
* add: --columns-per-row option for text autosizing. * add: --columns-per-row for text autosizing.
* add: --load-theme option to read and set a custom theme at runtime. * add: --load-theme to read and set a custom theme at runtime.
* add: --save-theme option to save current theme. * add: --save-theme to save current theme.
* add: --bikeshed option for random settings. * add: --bikeshed for random settings.
* add: --switch-buttons enables focus switching: buttons / input * add: --switch-buttons enables focus switching: buttons / input
components. Available for: --form, --inputbox, --mixedform, components. Available for: --form, --inputbox, --mixedform,
--passwordform, --passwordbox, --timebox and --datebox. --passwordform, --passwordbox, --timebox and --datebox.
* change: rename --esc-cancelvalue to --esc-return-cancel. * change: rename --esc-cancelvalue to --esc-return-cancel.
* change: form field value is printed like multibyte charachter string, * change: form field value is printed like multibyte charachter string,
previously widechar string. previously widechar string.
* change: --timebox output with zero padding.
* change: --datebox output mm and dd with zero padding.
* fix: --hline with empty string. * fix: --hline with empty string.
* fix: avoid to overlay the backtitle by setting a top margin. * fix: avoid to overlay the backtitle by setting a top margin.
* fix: avoid to overlay down shadow with menus and forms bottomdesc * fix: avoid to overlay down shadow with menus and forms bottomdesc
@ -25,8 +76,8 @@
* add: conf.text.cols_per_row to set a ratio for text autosizing. * add: conf.text.cols_per_row to set a ratio for text autosizing.
* add: timebox and datebox arrows and focus background for boxes. * add: timebox and datebox arrows and focus background for boxes.
* add: timebox and datebox UP key to switch focus. * add: timebox and datebox UP key to switch focus.
* add: bsddialog_init_notheme() in bsddialo_theme.h. * add: bsddialog_init_notheme() in bsddialog.h.
* add: bsddialog_hascolors() in bsddialo_theme.h. * add: bsddialog_hascolors() in bsddialog_theme.h.
* add: theme.form.bottomdesccolor and theme.menu.bottomdesccolor. * add: theme.form.bottomdesccolor and theme.menu.bottomdesccolor.
* add: conf.button.always_active to disable buttons/input-boxes switch. * add: conf.button.always_active to disable buttons/input-boxes switch.
* add: dynamic buttons margin. * add: dynamic buttons margin.
@ -60,8 +111,8 @@
- add: formheight autosizing. - add: formheight autosizing.
- add: dynamic item position. - add: dynamic item position.
* fix: bsddialog_gauge() with fd < 0. * fix: bsddialog_gauge() with fd < 0.
* fix: internal segmentation fault with disabled shadow.
* fix: bsddialog_gauge() refresh new text. * fix: bsddialog_gauge() refresh new text.
* fix: internal segmentation fault with disabled shadow.
* fix: center position without shadow. * fix: center position without shadow.
* fix: bsddialog_infobox() with zero text length. * fix: bsddialog_infobox() with zero text length.
* fix: text wrapping with more than 1024 words. * fix: text wrapping with more than 1024 words.
@ -92,7 +143,7 @@
* change: theme.button.[left|right]ch -> theme.button.[left|right]delim. * change: theme.button.[left|right]ch -> theme.button.[left|right]delim.
* change: theme.button.space -> theme.button.hmargin. * change: theme.button.space -> theme.button.hmargin.
* change: theme.menu.arrowcolor -> theme.dialog.arrowcolor. * change: theme.menu.arrowcolor -> theme.dialog.arrowcolor.
* change: default menu item depth 4 -> 2. * change: internal bsddialog_menuitem.depth factor 4 -> 2.
* fix: disable HOME, PPAGE, END and NPAGE keys in bsddialog_form(). * fix: disable HOME, PPAGE, END and NPAGE keys in bsddialog_form().
* fix: visible cursor for timebox.c and form.c in VM VirtualBox. * fix: visible cursor for timebox.c and form.c in VM VirtualBox.
* fix: mixedlist, center position of separator with big pad. * fix: mixedlist, center position of separator with big pad.
@ -106,7 +157,7 @@
2022-01-27 Version 0.1 2022-01-27 Version 0.1
* Common-Options: --ascii-lines, --backtitle <backtitle>, --begin-x <x>, * Options: --ascii-lines, --backtitle <backtitle>, --begin-x <x>,
--begin-y <y>, --cancel-label <label>, --clear, --colors, --cr-wrap, --begin-y <y>, --cancel-label <label>, --clear, --colors, --cr-wrap,
--date-format <format>, --defaultno, --default-button <label>, --date-format <format>, --defaultno, --default-button <label>,
--default-no, --default-item <name>, --disable-esc, --default-no, --default-item <name>, --disable-esc,
@ -131,4 +182,3 @@
--passwordbox, --passwordform, --pause, --radiolist, --rangebox, --passwordbox, --passwordform, --pause, --radiolist, --rangebox,
--textbox, --timebox, --treeview, --yesno. --textbox, --timebox, --treeview, --yesno.
* Manuals: bsddialog.1, bsddialog.3. * Manuals: bsddialog.1, bsddialog.3.

View File

@ -8,8 +8,8 @@ SOURCES= bsddialog.c util_theme.c
OBJECTS= $(SOURCES:.c=.o) OBJECTS= $(SOURCES:.c=.o)
LIBPATH= ./lib LIBPATH= ./lib
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
CFLAGS= -Wall -Wextra -Wno-unused-parameter -I$(LIBPATH) CFLAGS= -Wall -Wextra -I$(LIBPATH)
LDFLAGS= -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog LDFLAGS= -ltinfo -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
RM = rm -f RM = rm -f
all : $(OUTPUT) all : $(OUTPUT)

View File

@ -9,13 +9,13 @@ OBJECTS= ${SOURCES:.c=.o}
LIBPATH= ${.CURDIR}/lib LIBPATH= ${.CURDIR}/lib
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
CFLAGS+= -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter CFLAGS+= -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror
# `make -DDEBUG` # `make -DDEBUG`
.if defined(DEBUG) .if defined(DEBUG)
CFLAGS= -g -Wall -I${LIBPATH} CFLAGS= -g -Wall -I${LIBPATH}
LIBDEBUG= -DDEBUG LIBDEBUG= -DDEBUG
.endif .endif
LDFLAGS+= -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog LDFLAGS+= -ltinfow -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
BINDIR= /usr/local/bin BINDIR= /usr/local/bin
MAN= ${OUTPUT}.1 MAN= ${OUTPUT}.1

View File

@ -1,22 +1,8 @@
# BSDDialog 0.3 # BSDDialog 0.4
This project provides **bsddialog** and **libbsddialog**, an utility This project provides **bsddialog** and **libbsddialog**, an utility
and a library to build scripts and tools with TUI dialogs and widgets. and a library to build scripts and tools with TUI dialogs and widgets.
[Screenshots](https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074).
## Intro
Briefly:
<https://www.freebsd.org/status/report-2021-04-2021-06/bsddialog/>
Utility:
<https://alfonsosiciliano.gitlab.io/posts/2021-12-07-bsddialog.html>
Library:
<https://alfonsosiciliano.gitlab.io/posts/2022-01-16-libbsddialog.html>
Screenshots:
<https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074>
## Getting Started ## Getting Started
@ -48,9 +34,9 @@ Output:
**Dialogs:** **Dialogs:**
--checklist, --datebox, --form, --gauge, --inputbox, --menu, --mixedform, --calendar, --checklist, --datebox, --form, --gauge, --infobox, --inputbox,
--mixedgauge, --msgbox, --passwordbox, --passwordform, --pause, --radiolist, --menu, --mixedform, --mixedgauge, --msgbox, --passwordbox, --passwordform,
--rangebox, --textbox, --timebox, --treeview, --yesno. --pause, --radiolist, --rangebox, --textbox, --timebox, --treeview, --yesno.
**Manual** **Manual**
@ -72,6 +58,7 @@ Output:
and [Examples](https://gitlab.com/alfix/bsddialog/-/tree/main/examples_utility) and [Examples](https://gitlab.com/alfix/bsddialog/-/tree/main/examples_utility)
in the _Public Domain_ to build new projects: in the _Public Domain_ to build new projects:
``` ```
% sh ./examples_utility/calendar.sh
% sh ./examples_utility/checklist.sh % sh ./examples_utility/checklist.sh
% sh ./examples_utility/form.sh % sh ./examples_utility/form.sh
% sh ./examples_utility/gauge.sh % sh ./examples_utility/gauge.sh
@ -109,6 +96,7 @@ in the _Public Domain_ to build new projects:
``` ```
% cd examples_library % cd examples_library
% sh compile % sh compile
% ./calendar
% ./checklist % ./checklist
% ./datebox % ./datebox
% ./form % ./form

View File

@ -1,4 +1,5 @@
.\" .\"
.\"
.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano .\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
.\" .\"
.\" Redistribution and use in source and binary forms, with or without .\" Redistribution and use in source and binary forms, with or without
@ -22,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd August 29, 2022 .Dd September 23, 2022
.Dt BSDDIALOG 1 .Dt BSDDIALOG 1
.Os .Os
.Sh NAME .Sh NAME
@ -34,12 +35,19 @@
.Nm .Nm
.Fl Fl version .Fl Fl version
.Nm .Nm
.Op Fl Fl common-option .Op Fl Fl option
.Fl Fl dialog .Fl Fl dialog
.Ar text .Ar text
.Ar rows .Ar rows
.Ar cols .Ar cols
.Op Ar dialog-parameter .Op Ar dialog-argument
.Nm
.Fl Fl dialog1
.Ar ...
.Oo Fl Fl and-dialog
.Fl Fl dialog2
.Ar ...
.Oc ...
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm bsddialog .Nm bsddialog
@ -51,21 +59,24 @@ The options
and and
.Fl Fl version .Fl Fl version
print the list of options and the version, respectively, then exit. print the list of options and the version, respectively, then exit.
.Fl Fl and-dialog
builds another dialog unless the previous one returns Error, ESC or Cancel.
.Pp .Pp
The following options are available for each dialog.
.Ar text .Ar text
is a message printed inside the dialog, except for is a message printed inside the dialog.
.Fl Fl textbox
described later.
.Ar rows .Ar rows
and and
.Ar cols .Ar cols
are the height and width, 0 for autosize and -1 for fullscreen. are the height and width, 0 for autosize and -1 for fullscreen.
.Pp
The possible input got from the user interface is printed to standard error. The possible input got from the user interface is printed to standard error.
.Ss Common options .Ss Options
The following options can change the default behavior of the utility and are The following options can change the default behavior of the utility and are
common to some dialog. common to some dialog.
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl Fl alternate-screen
If available set alternate screen mode, see
.Xr terminfo 5 .
.It Fl Fl ascii-lines .It Fl Fl ascii-lines
Ascii characters to draw lines. Ascii characters to draw lines.
.It Fl Fl backtitle Ar backtitle .It Fl Fl backtitle Ar backtitle
@ -85,8 +96,10 @@ Zero padding with time or date output.
Label for the Label for the
.Dq Cancel .Dq Cancel
button. button.
.It Fl Fl clear .It Fl Fl clear-dialog
Hide the dialog at exit. Hide the dialog at exit.
.It Fl Fl clear-screen
Clear the screen, after the dialog exit if a dialog is built.
.It Fl Fl colors .It Fl Fl colors
Enable highlights for text, the following sequences are considered escapes: Enable highlights for text, the following sequences are considered escapes:
.Bl -column -compact .Bl -column -compact
@ -125,13 +138,19 @@ restore normal text.
Try to set the number of columns for a row of text with autosizing; default Try to set the number of columns for a row of text with autosizing; default
.Dv 10 . .Dv 10 .
.It Fl Fl cr-wrap .It Fl Fl cr-wrap
Replace new line with a space in Keep new line in
.Ar text . .Ar text
also if it constains a
.Dq \en ,
see
.Fl Fl text-unchanged .
.It Fl Fl date-format Ar format .It Fl Fl date-format Ar format
String accepted by String accepted by
.Xr strftime 3 .Xr strftime 3
to customize the output of to customize the output of
.Fl Fl datebox . .Fl Fl datebox
and
.Fl Fl calendar
.It Fl Fl default-button Ar label .It Fl Fl default-button Ar label
Focus on the button with Focus on the button with
.Ar label .Ar label
@ -146,18 +165,12 @@ Focus on
or or
.Dq \&No .Dq \&No
button on startup. button on startup.
.It Fl Fl defaultno
Equivalent to
.Fl Fl default-no .
.It Fl Fl disable-esc .It Fl Fl disable-esc
Disable ESC key to quit. Disable ESC key to quit.
.It Fl Fl esc-return-cancel .It Fl Fl esc-return-cancel
Exits with the ESC key returns
.Dq Cancel .Dq Cancel
button value if the ESC key is pressed. button value.
.It Fl Fl exit-label Ar label
Equivalent to
.Fl Fl ok-label .
.It Fl Fl extra-button .It Fl Fl extra-button
Add a button with Add a button with
.Dq Extra .Dq Extra
@ -184,14 +197,14 @@ Set
for for
.Dq Help .Dq Help
button. button.
.It Fl Fl help-print-name
Print the name of the focused item if the Help button is pressed also
with
.Fl Fl item-bottom-desc .
.It Fl Fl help-status .It Fl Fl help-status
Print also the selected items if the Print also the selected items if the
.Dq Help .Dq Help
button is pressed. button is pressed.
.It Fl Fl help-tags
Print the name of the focused item if the Help button is pressed also
with
.Fl Fl item-help .
.It Fl Fl hfile Ar filename .It Fl Fl hfile Ar filename
Open Open
.Ar filename .Ar filename
@ -208,11 +221,11 @@ Do not exit with unknown options.
Print Print
.Sq * .Sq *
to hide passwords while typing; whitespace otherwise. to hide passwords while typing; whitespace otherwise.
.It Fl Fl item-bottom-desc
Set a help string for each item of a Checklist, Form, Menu, Mixedform,
Passwordform, Radiolist and Treeview to display at the bottom screen side.
.It Fl Fl item-depth .It Fl Fl item-depth
Specify a margin for items, available for Checklist, Menu and Radiolist. Specify a margin for items, available for Checklist, Menu and Radiolist.
.It Fl Fl item-help
Set a help string for each element of a Checklist, Form, Menu, Mixedform,
Passwordform, Radiolist and Treeview to display at the bottom screen side.
.It Fl Fl item-prefix .It Fl Fl item-prefix
Set a string to prefix each item of a Checklist, Menu, Radiolist or Treeview. Set a string to prefix each item of a Checklist, Menu, Radiolist or Treeview.
.It Fl Fl load-theme Ar file .It Fl Fl load-theme Ar file
@ -228,59 +241,46 @@ default 2048.
Do not show Do not show
.Dq Cancel .Dq Cancel
button. button.
.It Fl Fl no-collapse .It Fl Fl no-descriptions
Do not replace a TAB character with a space in
.Ar text .
.It Fl Fl no-items
Do not display items desciption, for Checklist, Menu, Radiolist or Treeview. Do not display items desciption, for Checklist, Menu, Radiolist or Treeview.
.It Fl Fl no-label Ar label
Equivalent to
.Fl Fl cancel-label .
.It Fl Fl no-lines .It Fl Fl no-lines
Do not draw borders and lines. Do not draw borders and lines.
.It Fl Fl no-nl-expand .It Fl Fl no-names
do not consider the sequence Do not display items name, for Checklist, Menu and Radiolist.
.Dq \en
like new line.
.It Fl Fl no-ok .It Fl Fl no-ok
Do not draw Do not draw
.Dq OK .Dq OK
button. button.
.It Fl Fl no-shadow .It Fl Fl no-shadow
No not draw the shadow of the dialog. No not draw the shadow of the dialog.
.It Fl Fl no-tags
Do not display items name, for Checklist, Menu and Radiolist.
.It Fl Fl nocancel
Equivalent to
.Fl Fl no-cancel .
.It Fl Fl nook
Equivalent to
.Fl Fl no-ok .
.It Fl Fl ok-label Ar label .It Fl Fl ok-label Ar label
Set Set
.Ar label .Ar label
for for
.Dq OK .Dq OK
button. button.
.It Fl Fl normal-screen
If available set normal screen mode, see
.Xr terminfo 5 .
.It Fl Fl output-fd Ar fd .It Fl Fl output-fd Ar fd
Print input from user interface to the specified file descriptor. Print input from user interface to the specified file descriptor.
.It Fl Fl output-separator Ar sep .It Fl Fl output-separator Ar sep
Set a sepator for the items in output, default whitespace. Set a sepator for the items in output, default whitespace.
.It Fl Fl print-maxsize .It Fl Fl print-maxsize
Screen size. Screen size.
This option can be used without a dialog.
.It Fl Fl print-size .It Fl Fl print-size
Print Dialog height and widget at exit. Print Dialog height and widget at exit.
.It Fl Fl print-version .It Fl Fl print-version
Print version. Print version.
This option can be used without a dialog.
.It Fl Fl quoted .It Fl Fl quoted
Quote items in output, default only when necessary. Quote items in output, default only when necessary.
.It Fl Fl save-theme Ar file .It Fl Fl save-theme Ar file
Save the current theme. Save the current theme.
This option can be used without a dialog.
.It Fl Fl separate-output .It Fl Fl separate-output
Separate selected items with a new line and avoid to quote. Separate selected items with a new line and avoid to quote.
.It Fl Fl separator Ar sep
Equivalent to
.Fl Fl output-separator .
.It Fl Fl shadow .It Fl Fl shadow
Show a pseudo shadow for the dialog, enabled by default. Show a pseudo shadow for the dialog, enabled by default.
.It Fl Fl single-quoted .It Fl Fl single-quoted
@ -302,12 +302,29 @@ Suitable for:
.Fl Fl mixedform , .Fl Fl mixedform ,
.Fl Fl passwordbox , .Fl Fl passwordbox ,
.Fl Fl passwordform , .Fl Fl passwordform ,
.Fl Fl timebox .Fl Fl timebox ,
.Fl Fl calendar
and and
.Fl Fl datebox . .Fl Fl datebox .
.It Fl Fl tab-escape
Replace
.Dq \et
with a tab in
.Ar text .
.It Fl Fl tab-len Ar spaces .It Fl Fl tab-len Ar spaces
Number of spaces to print a TAB in Number of spaces to print a TAB in
.Ar text . .Ar text .
.It Fl Fl text-unchanged
By default the
.Ar text
is changed before to be printed.
If it contains at least a
.Dq \en
each new line and TAB is converted to a space, subsequent spaces are merged.
Otherwise new line characters are preserved and a TAB becomes a space.
This option disable the
.Ar text
modification.
.It Fl Fl theme Ar theme .It Fl Fl theme Ar theme
Set a graphical style: blackwhite, bsddialog, flat or dialog. Set a graphical style: blackwhite, bsddialog, flat or dialog.
.It Fl Fl time-format Ar format .It Fl Fl time-format Ar format
@ -317,16 +334,12 @@ to customize the output of
.Fl Fl timebox . .Fl Fl timebox .
.It Fl Fl title Ar title .It Fl Fl title Ar title
Dialog title. Dialog title.
.It Fl Fl trim
remove consecutive spaces in
.Ar text .
.It Fl Fl yes-label Ar label
Equivalent to
.Fl Fl ok-label .
.El .El
.Ss Dialogs .Ss Dialogs
The following dialogs are available: The following dialogs are available:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl Fl calendar Ar text Ar rows Ar cols Op Ar day Ar month Ar year
Dialog to select a date.
.It Fl Fl checklist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \ .It Fl Fl checklist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \
Ar status Oc ... Ar status Oc ...
Checklist to select some item from a list via the SPACE key. Checklist to select some item from a list via the SPACE key.
@ -342,7 +355,7 @@ or
The names of the selected items are printed to standard error. The names of the selected items are printed to standard error.
.Ar menurows .Ar menurows
is the graphical height of the list, 0 for autosize. is the graphical height of the list, 0 for autosize.
.It Fl Fl datebox Ar text Ar rows Ar cols Op Ar year Ar month Ar day .It Fl Fl datebox Ar text Ar rows Ar cols Op Ar day Ar month Ar year
Dialog to select a date. Dialog to select a date.
.It Fl Fl form Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \ .It Fl Fl form Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters Oc ... Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters Oc ...
@ -393,7 +406,7 @@ Dialog to get a string in input,
.Ar init .Ar init
is the default value. is the default value.
.It Fl Fl menu Ar text Ar rows Ar cols Ar menurows Oo Ar name desc Oc ... .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. Builds a menu to select an item from a list, Space key is equivalent to Enter.
An item has a An item has a
.Ar name .Ar name
and a and a
@ -461,6 +474,7 @@ a blank line,
Dialog to diplay a message without the Dialog to diplay a message without the
.Dq Cancel .Dq Cancel
button. button.
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
.It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init .It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init
Dialog to get a password, Dialog to get a password,
.Ar init .Ar init
@ -522,6 +536,7 @@ buttons are renamed
.Dq Yes .Dq Yes
and and
.Dq \&No . .Dq \&No .
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
.El .El
.Sh EXIT STATUS .Sh EXIT STATUS
The The
@ -574,6 +589,10 @@ Checklist:
Form: Form:
.Dl bsddialog --form Form 0 0 0 L1: 0 0 X 0 4 20 25 L2: 1 0 Y 1 4 20 25 .Dl bsddialog --form Form 0 0 0 L1: 0 0 X 0 4 20 25 L2: 1 0 Y 1 4 20 25
.Pp .Pp
Multi-dialog:
.Dl bsddialog --normal-screen --begin-y 1 --yesno Continue? 0 0 \e \
--and-dialog --begin-y 10 --infobox Yes 0 0
.Pp
Bikeshed: Bikeshed:
.Dl bsddialog --bikeshed --inputbox Example 0 0 .Dl bsddialog --bikeshed --inputbox Example 0 0
.Pp .Pp
@ -614,6 +633,27 @@ do
i=`expr $i + 1` i=`expr $i + 1`
done | bsddialog --title Gauge --gauge "Starting..." 10 70 done | bsddialog --title Gauge --gauge "Starting..." 10 70
.Ed .Ed
.Sh COMPATIBILITY
Outdated options are retained for compatibility, properly equivalent options are
used:
.Bd -literal -offset indent -compact
Obsolete Equivalent
--and-widget --and-dialog
--calendar <text> 2 <cols> --calendar <text> 0 <cols>
--clear --clear-screen
--defaultno --default-no
--exit-label --ok-label
--help-tags --help-print-name
--item-help --item-bottom-desc
--keep-tite --alternate-screen
--no-items --no-descriptions
--no-label --cancel-label
--no-tags --no-names
--nocancel --no-cancel
--nook --no-ok
--separator --output-separator
--yes-label --ok-label
.Ed
.Sh SEE ALSO .Sh SEE ALSO
.Xr bsddialog 3 .Xr bsddialog 3
.Sh HISTORY .Sh HISTORY
@ -633,7 +673,8 @@ provides a subset of the functionality described in the
manual. manual.
The following features were reimplemented: The following features were reimplemented:
.Pp .Pp
Common options: Options:
.Fl Fl and-widget ,
.Fl Fl ascii-lines , .Fl Fl ascii-lines ,
.Fl Fl backtitle , .Fl Fl backtitle ,
.Fl Fl cancel-label , .Fl Fl cancel-label ,
@ -658,14 +699,13 @@ Common options:
.Fl Fl ignore , .Fl Fl ignore ,
.Fl Fl insecure , .Fl Fl insecure ,
.Fl Fl item-help , .Fl Fl item-help ,
.Fl Fl keep-tite ,
.Fl Fl max-input , .Fl Fl max-input ,
.Fl Fl no-cancel , .Fl Fl no-cancel ,
.Fl Fl nocancel , .Fl Fl nocancel ,
.Fl Fl no-collapse ,
.Fl Fl no-items , .Fl Fl no-items ,
.Fl Fl no-label , .Fl Fl no-label ,
.Fl Fl no-lines , .Fl Fl no-lines ,
.Fl Fl no-nl-expand ,
.Fl Fl no-ok , .Fl Fl no-ok ,
.Fl Fl nook , .Fl Fl nook ,
.Fl Fl no-shadow , .Fl Fl no-shadow ,
@ -687,11 +727,11 @@ Common options:
.Fl Fl tab-len , .Fl Fl tab-len ,
.Fl Fl time-format , .Fl Fl time-format ,
.Fl Fl title , .Fl Fl title ,
.Fl Fl trim ,
.Fl Fl version , .Fl Fl version ,
.Fl Fl yes-label . .Fl Fl yes-label .
.Pp .Pp
Dialogs: Dialogs:
.Fl Fl calendar ,
.Fl Fl checklist , .Fl Fl checklist ,
.Fl Fl form , .Fl Fl form ,
.Fl Fl gauge , .Fl Fl gauge ,
@ -715,8 +755,10 @@ Some feature differs in input, output, or behavior.
Compatibility is not a priority for future development. Compatibility is not a priority for future development.
.Sh THANKS TO .Sh THANKS TO
.An Baptiste Daroussin .An Baptiste Daroussin
.Aq Mt bapt@FreeBSD.org .Aq Mt bapt@FreeBSD.org ,
and
.An \&Ed Maste .An \&Ed Maste
.Aq Mt emaste@FreeBSD.org .Aq Mt emaste@FreeBSD.org
and
.An Juraj Lutter
.Aq Mt otis@FreeBSD.org
for suggestions, help, and testing. for suggestions, help, and testing.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/*-
* SPDX-License-Identifier: CC0-1.0
*
* Written in 2022 by Alfonso Sabato Siciliano.
* To the extent possible under law, the author has dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty, see:
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <bsddialog.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
int main()
{
int output;
unsigned int yy, mm, dd;
struct bsddialog_conf conf;
time_t cal;
struct tm *localtm;
time(&cal);
localtm = localtime(&cal);
yy = localtm->tm_year + 1900;
mm = localtm->tm_mon + 1;
dd = localtm->tm_mday;
if (bsddialog_init() == BSDDIALOG_ERROR) {
printf("Error: %s\n", bsddialog_geterror());
return (1);
}
bsddialog_initconf(&conf);
conf.title = "calendar";
output = bsddialog_calendar(&conf, "Example", 18, 40, &yy, &mm, &dd);
bsddialog_end();
switch (output) {
case BSDDIALOG_OK:
printf("Date: %u/%u/%u", yy, mm, dd);
break;
case BSDDIALOG_CANCEL:
printf("Cancel");
break;
case BSDDIALOG_ERROR:
printf("Error: %s", bsddialog_geterror());
break;
}
printf("\n");
return (output);
}

View File

@ -10,7 +10,7 @@
libpath=../lib libpath=../lib
examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \ examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
datebox form timebox rangebox pause" datebox form timebox rangebox pause calendar"
rm -f $examples rm -f $examples

View File

@ -27,7 +27,7 @@ int main()
{"Password:", 2, 0, "", 2, 10, 30, 50, NULL, H, "desc 3"} {"Password:", 2, 0, "", 2, 10, 30, 50, NULL, H, "desc 3"}
}; };
/* Optional, unless for unicode/multicolum charachters */ /* Optional, unless for unicode/multi-column characters */
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
if (bsddialog_init() == BSDDIALOG_ERROR) { if (bsddialog_init() == BSDDIALOG_ERROR) {
@ -56,4 +56,4 @@ int main()
} }
return (output); return (output);
} }

View File

@ -0,0 +1,34 @@
#!/bin/sh
#-
# SPDX-License-Identifier: CC0-1.0
#
# Written in 2022 by Alfonso Sabato Siciliano.
#
# To the extent possible under law, the author has dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty, see:
# <http://creativecommons.org/publicdomain/zero/1.0/>.
: ${BSDDIALOG_ERROR=255}
: ${BSDDIALOG_OK=0}
: ${BSDDIALOG_CANCEL=1}
: ${BSDDIALOG_ESC=5}
DATE=$(./bsddialog --title " calendar " --date-format "%x" \
--calendar "Hello World!" 20 40 \
3>&1 1>&2 2>&3 3>&-)
case $? in
$BSDDIALOG_ERROR )
exit 1
;;
$BSDDIALOG_ESC )
echo "[ESC]"
;;
$BSDDIALOG_CANCEL )
echo "[Cancel]"
;;
$BSDDIALOG_OK )
echo "[OK] $DATE"
;;
esac

View File

@ -14,8 +14,7 @@
: ${BSDDIALOG_CANCEL=1} : ${BSDDIALOG_CANCEL=1}
: ${BSDDIALOG_ESC=5} : ${BSDDIALOG_ESC=5}
TIME=$(./bsddialog --title " timebox " \ TIME=$(./bsddialog --title " timebox " --timebox "Hello World!" 8 25 \
--timebox "Tab / Left / Right to move\nUp / Down to select" 10 40 \
3>&1 1>&2 2>&3 3>&-) 3>&1 1>&2 2>&3 3>&-)
case $? in case $? in

View File

@ -3,15 +3,15 @@
# #
# Written in 2021 by Alfonso Sabato Siciliano # Written in 2021 by Alfonso Sabato Siciliano
VERSION = 0.3 VERSION = 0.4
LIBRARY = bsddialog LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so} LIBRARY_SO = lib${LIBRARY:=.so}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
messagebox.c textbox.c theme.c timebox.c lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
OBJECTS = $(SOURCES:.c=.o) OBJECTS = $(SOURCES:.c=.o)
CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra -Wno-implicit-fallthrough \ CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra \
-Werror -fpic -Wno-implicit-fallthrough -Werror -fpic
LDFLAGS = -lncursesw -ltinfo LDFLAGS = -lncursesw -ltinfo
LIBFLAG = -shared LIBFLAG = -shared

View File

@ -3,13 +3,13 @@
# #
# Written in 2021 by Alfonso Sabato Siciliano # Written in 2021 by Alfonso Sabato Siciliano
VERSION = 0.3 VERSION = 0.4
LIBRARY = bsddialog LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so} LIBRARY_SO = lib${LIBRARY:=.so}
LIBRARY_A = lib${LIBRARY:=.a} LIBRARY_A = lib${LIBRARY:=.a}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
messagebox.c textbox.c theme.c timebox.c lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
OBJECTS = ${SOURCES:.c=.o} OBJECTS = ${SOURCES:.c=.o}
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra
LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \ LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \

View File

@ -327,7 +327,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
wrefresh(bar); wrefresh(bar);
/* getch(); port ncurses shows nothing */ /* getch(); alternate mode (port devel/ncurses) shows nothing */
delwin(bar); delwin(bar);
end_dialog(conf, shadow, widget, textpad); end_dialog(conf, shadow, widget, textpad);

View File

@ -22,11 +22,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd August 29, 2022 .Dd September 23, 2022
.Dt BSDDIALOG 3 .Dt BSDDIALOG 3
.Os .Os
.Sh NAME .Sh NAME
.Nm bsddialog_backtitle , .Nm bsddialog_backtitle ,
.Nm bsddialog_calendar ,
.Nm bsddialog_clearterminal , .Nm bsddialog_clearterminal ,
.Nm bsddialog_color , .Nm bsddialog_color ,
.Nm bsddialog_color_attrs , .Nm bsddialog_color_attrs ,
@ -62,6 +63,16 @@
.Ft int .Ft int
.Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle" .Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle"
.Ft int .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 .Fo bsddialog_checklist
.Fa "struct bsddialog_conf *conf" .Fa "struct bsddialog_conf *conf"
.Fa "const char *text" .Fa "const char *text"
@ -75,7 +86,7 @@
.Ft int .Ft int
.Fn bsddialog_clearterminal "void" .Fn bsddialog_clearterminal "void"
.Ft int .Ft int
.Fo bsddialog_datebox" .Fo bsddialog_datebox
.Fa "struct bsddialog_conf *conf" .Fa "struct bsddialog_conf *conf"
.Fa "const char *text" .Fa "const char *text"
.Fa "int rows" .Fa "int rows"
@ -476,7 +487,8 @@ function.
buttons always active, avoidind focus switch between buttons and input fields or buttons always active, avoidind focus switch between buttons and input fields or
input boxes in input boxes in
.Fn bsddialog_form , .Fn bsddialog_form ,
.Fn bsddialog_datebox .Fn bsddialog_datebox ,
.Fn bsddialog_calendar
and and
.Fn bsddialog_timebox . .Fn bsddialog_timebox .
.It Fa conf.button.without_ok .It Fa conf.button.without_ok
@ -515,7 +527,10 @@ to true,
and and
.Fa conf.x .Fa conf.x
to to
.Dv BSDDIALOG_CENTER . .Dv BSDDIALOG_CENTER ,
.Fa conf.text.cols_per_row
to
.Dv 10 .
.Pp .Pp
.Fn bsddialog_infobox .Fn bsddialog_infobox
builds a dialog without buttons and returns instantly. builds a dialog without buttons and returns instantly.
@ -531,8 +546,10 @@ builds a dialog waiting until the timeout in
.Fa seconds .Fa seconds
expires or a button is pressed. expires or a button is pressed.
.Pp .Pp
.Fn bsddialog_calendar
and
.Fn bsddialog_datebox .Fn bsddialog_datebox
builds a dialog to select a date, build a dialog to select a date,
.Fa yy , .Fa yy ,
.Fa mm , .Fa mm ,
and and
@ -606,14 +623,14 @@ builds a dialog with collections of checklists, radiolists and separators.
A collection is a set defined like: A collection is a set defined like:
.Pp .Pp
.Bd -literal -offset indent -compact .Bd -literal -offset indent -compact
enum bsddialog_grouptype { enum bsddialog_menutype {
BSDDIALOG_CHECKLIST, BSDDIALOG_CHECKLIST,
BSDDIALOG_RADIOLIST, BSDDIALOG_RADIOLIST,
BSDDIALOG_SEPARATOR, BSDDIALOG_SEPARATOR,
}; };
struct bsddialog_menugroup { struct bsddialog_menugroup {
enum bsddialog_grouptype type; enum bsddialog_menutype type;
unsigned int nitems; unsigned int nitems;
struct bsddialog_menuitem *items; struct bsddialog_menuitem *items;
}; };
@ -1013,7 +1030,7 @@ struct bsddialog_menuitem check[2] = {
struct bsddialog_menuitem sep[1] = { struct bsddialog_menuitem sep[1] = {
{ "3", true, 0, "Radiolist", "(desc)", "" } { "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" }, { "4", true, 0, "Name 1", "Desc 1", "Radio Bottom Desc 1" },
{ "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" } { "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" }
}; };

View File

@ -30,7 +30,7 @@
#include <stdbool.h> #include <stdbool.h>
#define LIBBSDDIALOG_VERSION "0.3" #define LIBBSDDIALOG_VERSION "0.4"
/* Exit status */ /* Exit status */
#define BSDDIALOG_ERROR -1 #define BSDDIALOG_ERROR -1
@ -136,14 +136,14 @@ struct bsddialog_menuitem {
const char *bottomdesc; const char *bottomdesc;
}; };
enum bsddialog_grouptype { enum bsddialog_menutype {
BSDDIALOG_CHECKLIST, BSDDIALOG_CHECKLIST,
BSDDIALOG_RADIOLIST, BSDDIALOG_RADIOLIST,
BSDDIALOG_SEPARATOR, BSDDIALOG_SEPARATOR,
}; };
struct bsddialog_menugroup { struct bsddialog_menugroup {
enum bsddialog_grouptype type; enum bsddialog_menutype type;
unsigned int nitems; unsigned int nitems;
struct bsddialog_menuitem *items; struct bsddialog_menuitem *items;
}; };
@ -173,6 +173,10 @@ int bsddialog_clearterminal(void);
const char *bsddialog_geterror(void); const char *bsddialog_geterror(void);
/* Dialogs */ /* 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 int
bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows, bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
int cols, unsigned int menurows, unsigned int nitems, int cols, unsigned int menurows, unsigned int nitems,

View File

@ -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);
}

View File

@ -424,34 +424,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
} else } else
notext += *menurows; notext += *menurows;
/* cols autosize, rows autosize, rows fullscreen, menu particularity */ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext,
if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) { &wtext) != 0)
if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, return (BSDDIALOG_ERROR);
&htext, &wtext) != 0)
return (BSDDIALOG_ERROR);
}
if (cols == BSDDIALOG_AUTOSIZE) if (cols == BSDDIALOG_AUTOSIZE)
*w = widget_min_width(conf, wtext, linelen + 4, &bs); *w = widget_min_width(conf, wtext, linelen + 4, &bs);
if (rows == BSDDIALOG_AUTOSIZE) { if (rows == BSDDIALOG_AUTOSIZE) {
if (*menurows == 0) { if (*menurows == BSDDIALOG_AUTOSIZE) {
menusize = widget_max_height(conf) - HBORDERS - menusize = widget_max_height(conf) - HBORDERS -
2 /*buttons*/ - htext; 2 /*buttons*/ - htext;
menusize = MIN(menusize, nitems + 2); menusize = MIN(menusize, nitems + 2);
*menurows = menusize - 2 < 0 ? 0 : menusize - 2; *menurows = menusize - 2 < 0 ? 0 : menusize - 2;
} } else /* h autosize with fixed menurows */
else /* h autosize with fixed menurows */
menusize = *menurows + 2; menusize = *menurows + 2;
*h = widget_min_height(conf, htext, menusize, true); *h = widget_min_height(conf, htext, menusize, true);
/* } else { /* fixed rows */
* avoid menurows overflow and if (*menurows == BSDDIALOG_AUTOSIZE) {
* with rows=AUTOSIZE menurows!=0 becomes max-menurows
*/
*menurows = MIN(*h - 6 - htext, (int)*menurows);
} else {
if (*menurows == 0) {
if (*h - 6 - htext <= 0) if (*h - 6 - htext <= 0)
*menurows = 0; /* form_checksize() will check */ *menurows = 0; /* form_checksize() will check */
else 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); return (0);
} }

View File

@ -921,11 +921,8 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
*h = maxheight; *h = maxheight;
else if (rows < BSDDIALOG_FULLSCREEN) else if (rows < BSDDIALOG_FULLSCREEN)
RETURN_ERROR("Negative (less than -1) height"); RETURN_ERROR("Negative (less than -1) height");
else if (rows > BSDDIALOG_AUTOSIZE) { else if (rows > BSDDIALOG_AUTOSIZE) /* fixed rows */
if ((*h = rows) > maxheight) *h = MIN(rows, maxheight); /* rows is at most maxheight */
RETURN_ERROR("Height too big (> terminal height - "
"shadow)");
}
/* rows == AUTOSIZE: each widget has to set its size */ /* rows == AUTOSIZE: each widget has to set its size */
if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR) 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; *w = maxwidth;
else if (cols < BSDDIALOG_FULLSCREEN) else if (cols < BSDDIALOG_FULLSCREEN)
RETURN_ERROR("Negative (less than -1) width"); RETURN_ERROR("Negative (less than -1) width");
else if (cols > BSDDIALOG_AUTOSIZE) { else if (cols > BSDDIALOG_AUTOSIZE) /* fixed cols */
if ((*w = cols) > maxwidth) *w = MIN(cols, maxwidth); /* cols is at most maxwidth */
RETURN_ERROR("Width too big (> terminal width - "
"shadow)");
}
/* cols == AUTOSIZE: each widget has to set its size */ /* cols == AUTOSIZE: each widget has to set its size */
return (0); return (0);

View File

@ -43,6 +43,9 @@ extern bool hastermcolors;
refresh(); \ refresh(); \
} while (0) } while (0)
/* date */
#define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
/* unicode */ /* unicode */
unsigned int strcols(const char *mbstring); unsigned int strcols(const char *mbstring);
int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col); int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col);

View File

@ -99,7 +99,9 @@ int bsddialog_end(void)
int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle) 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) if (conf->no_lines != true)
mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE, mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
SCREENCOLS - 2); SCREENCOLS - 2);

View File

@ -36,7 +36,6 @@
#include "bsddialog_theme.h" #include "bsddialog_theme.h"
#include "lib_util.h" #include "lib_util.h"
#define DEPTH 2
#define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */ #define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */
enum menumode { enum menumode {
@ -277,7 +276,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
colorname = focus ? t.menu.f_namecolor : t.menu.namecolor; colorname = focus ? t.menu.f_namecolor : t.menu.namecolor;
if (conf->menu.no_name == false) { if (conf->menu.no_name == false) {
wattron(pad, colorname); 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); wattroff(pad, colorname);
} }
@ -290,8 +289,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
if (conf->menu.no_desc == false) { if (conf->menu.no_desc == false) {
wattron(pad, colordesc); wattron(pad, colordesc);
if (conf->menu.no_name) if (conf->menu.no_name)
mvwaddstr(pad, y, pos.xname + item->depth * DEPTH, mvwaddstr(pad, y, pos.xname + item->depth, item->desc);
item->desc);
else else
mvwaddstr(pad, y, pos.xdesc, item->desc); mvwaddstr(pad, y, pos.xdesc, item->desc);
wattroff(pad, colordesc); wattroff(pad, colordesc);
@ -307,7 +305,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
mbtowc(&shortcut, item->desc, MB_CUR_MAX); mbtowc(&shortcut, item->desc, MB_CUR_MAX);
else else
mbtowc(&shortcut, item->name, MB_CUR_MAX); 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); wattroff(pad, colorshortcut);
} }
@ -362,34 +360,25 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
} else } else
notext += *menurows; notext += *menurows;
/* cols autosize, rows autosize, rows fullscreen, menu particularity */ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, &htext,
if (cols == BSDDIALOG_AUTOSIZE || rows <= BSDDIALOG_AUTOSIZE) { &wtext) != 0)
if (text_size(conf, rows, cols, text, &bs, notext, linelen + 4, return (BSDDIALOG_ERROR);
&htext, &wtext) != 0)
return (BSDDIALOG_ERROR);
}
if (cols == BSDDIALOG_AUTOSIZE) if (cols == BSDDIALOG_AUTOSIZE)
*w = widget_min_width(conf, wtext, linelen + 4, &bs); *w = widget_min_width(conf, wtext, linelen + 4, &bs);
if (rows == BSDDIALOG_AUTOSIZE) { if (rows == BSDDIALOG_AUTOSIZE) {
if (*menurows == 0) { if (*menurows == BSDDIALOG_AUTOSIZE) {
menusize = widget_max_height(conf) - HBORDERS - menusize = widget_max_height(conf) - HBORDERS -
2 /*buttons*/ - htext; 2 /*buttons*/ - htext;
menusize = MIN(menusize, nitems + 2); menusize = MIN(menusize, nitems + 2);
*menurows = menusize - 2 < 0 ? 0 : menusize - 2; *menurows = menusize - 2 < 0 ? 0 : menusize - 2;
} } else /* h autosize with fixed menurows */
else /* h autosize with fixed menurows */
menusize = *menurows + 2; menusize = *menurows + 2;
*h = widget_min_height(conf, htext, menusize, true); *h = widget_min_height(conf, htext, menusize, true);
/* } else { /* fixed rows */
* avoid menurows overflow and if (*menurows == BSDDIALOG_AUTOSIZE) {
* with rows=AUTOSIZE menurows!=0 becomes max-menurows
*/
*menurows = MIN(*h - 6 - htext, (int)*menurows);
} else {
if (*menurows == 0) {
if (*h - 6 - htext <= 0) if (*h - 6 - htext <= 0)
*menurows = 0; /* menu_checksize() will check */ *menurows = 0; /* menu_checksize() will check */
else 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); 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.maxname = conf->menu.no_name ? 0 : pos.maxname;
pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc; pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc;
pos.maxdepth = DEPTH * pos.maxdepth;
pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0); pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0);
pos.xname = pos.xselector + pos.selectorlen + 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; movefocus = next != abs;
break; break;
case ' ': /* Space */ case ' ': /* Space */
if (pritems[abs].type == MENUMODE) if (pritems[abs].type == MENUMODE) {
break; retval = bs.value[bs.curr];
else if (pritems[abs].type == CHECKLISTMODE) 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; pritems[abs].on = !pritems[abs].on;
else { /* RADIOLISTMODE */ } else { /* RADIOLISTMODE */
for (i = abs - pritems[abs].index; for (i = abs - pritems[abs].index;
i < totnitems && i < totnitems &&
pritems[i].group == pritems[abs].group; pritems[i].group == pritems[abs].group;

View File

@ -103,7 +103,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
struct buttons bs) struct buttons bs)
{ {
bool hastext, loop; 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; WINDOW *widget, *textpad, *shadow;
wint_t input; wint_t input;
@ -120,12 +120,13 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
true) != 0) true) != 0)
return (BSDDIALOG_ERROR); return (BSDDIALOG_ERROR);
printrows = h - 4;
ytextpad = 0; ytextpad = 0;
getmaxyx(textpad, htextpad, unused); getmaxyx(textpad, htextpad, unused);
unused++; /* fix unused error */ unused++; /* fix unused error */
textupdate(widget, textpad, htextpad, ytextpad, hastext);
loop = true; loop = true;
while (loop) { while (loop) {
textupdate(widget, textpad, htextpad, ytextpad, hastext);
doupdate(); doupdate();
if (get_wch(&input) == ERR) if (get_wch(&input) == ERR)
continue; continue;
@ -160,6 +161,30 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
wnoutrefresh(widget); wnoutrefresh(widget);
} }
break; 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): case KEY_F(1):
if (conf->key.f1_file == NULL && if (conf->key.f1_file == NULL &&
conf->key.f1_message == 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) textpad, text, &bs, true) != 0)
return (BSDDIALOG_ERROR); return (BSDDIALOG_ERROR);
printrows = h - 4;
getmaxyx(textpad, htextpad, unused); getmaxyx(textpad, htextpad, unused);
ytextpad = 0; ytextpad = 0;
textupdate(widget, textpad, htextpad, ytextpad, hastext); 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 */ /* Important to fix grey lines expanding screen */
refresh(); refresh();
break; 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: default:
if (shortcut_buttons(input, &bs)) { if (shortcut_buttons(input, &bs)) {
retval = bs.value[bs.curr]; retval = bs.value[bs.curr];

View File

@ -258,7 +258,6 @@ int bsddialog_set_theme(struct bsddialog_theme *theme)
int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
{ {
if (newtheme == BSDDIALOG_THEME_FLAT) { if (newtheme == BSDDIALOG_THEME_FLAT) {
bsddialog_set_theme(&dialogtheme); bsddialog_set_theme(&dialogtheme);
t.dialog.lineraisecolor = t.dialog.linelowercolor; t.dialog.lineraisecolor = t.dialog.linelowercolor;

View File

@ -39,7 +39,7 @@
#define MINWTIME 14 /* 3 windows and their borders */ #define MINWTIME 14 /* 3 windows and their borders */
static void 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) const void *value, bool focus)
{ {
int h, l, w; int h, l, w;
@ -167,7 +167,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
loop = focusbuttons = true; loop = focusbuttons = true;
while (loop) { while (loop) {
for (i = 0; i < 3; i++) 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); sel == i);
if (get_wch(&input) == ERR) 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 } { "October", 31 }, { "November", 30 }, { "December", 31 }
}; };
#define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
for (i = 0 ; i < 3; i++) { for (i = 0 ; i < 3; i++) {
if (c[i].value > c[i].max) if (c[i].value > c[i].max)
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[i].value = 1;
} }
c[2].max = m[c[1].value -1].days; 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; c[2].max = 29;
if (c[2].value > c[2].max) if (c[2].value > c[2].max)
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; sel = -1;
loop = focusbuttons = true; loop = focusbuttons = true;
while (loop) { while (loop) {
drawquare(conf, c[0].win, "%4d", &c[0].value, sel == 0); drawsquare(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[1].win, "%9s", m[c[1].value-1].name,
sel == 1); 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) if (get_wch(&input) == ERR)
continue; continue;
@ -456,7 +454,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
/* if mount change */ /* if mount change */
c[2].max = m[c[1].value -1].days; c[2].max = m[c[1].value -1].days;
/* if year change */ /* 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; c[2].max = 29;
/* set new day */ /* set new day */
if (c[2].value > c[2].max) 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 */ /* if mount change */
c[2].max = m[c[1].value -1].days; c[2].max = m[c[1].value -1].days;
/* if year change */ /* 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; c[2].max = 29;
/* set new day */ /* set new day */
if (c[2].value > c[2].max) 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); end_dialog(conf, shadow, widget, textpad);
return (retval); return (retval);
} }

View File

@ -100,7 +100,7 @@ static struct property p[NPROPERTY] = {
{ "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor} { "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor}
}; };
static char *color[8] = { static const char *color[8] = {
"black", "black",
"red", "red",
"green", "green",
@ -111,7 +111,15 @@ static char *color[8] = {
"white" "white"
}; };
int savetheme(const char *file, char *errbuf, const char *version) #define EXIT_FMTERROR(fmt, ...) do { \
bsddialog_end(); \
printf("Error: "); \
printf(fmt, __VA_ARGS__); \
printf(".\n"); \
exit (255); \
} while (0)
void savetheme(const char *file, const char *version)
{ {
int i; int i;
unsigned int flags; unsigned int flags;
@ -119,20 +127,14 @@ int savetheme(const char *file, char *errbuf, const char *version)
time_t clock; time_t clock;
FILE *fp; FILE *fp;
if (bsddialog_get_theme(&t) != BSDDIALOG_OK) { if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
sprintf(errbuf, "Cannot save theme: %s", bsddialog_geterror()); EXIT_FMTERROR("cannot save theme: %s", bsddialog_geterror());
return (BSDDIALOG_ERROR);
}
if(time(&clock) < 0) { if(time(&clock) < 0)
sprintf(errbuf, "Cannot save profile (getting current time)"); EXIT_FMTERROR("%s", "cannot save profile getting current time");
return (BSDDIALOG_ERROR);
}
if ((fp = fopen(file, "w")) == NULL) { if ((fp = fopen(file, "w")) == NULL)
sprintf(errbuf, "Cannot open %s to save profile", file); EXIT_FMTERROR("cannot open %s to save profile", file);
return (BSDDIALOG_ERROR);
}
fprintf(fp, "### bsddialog theme - %s", ctime(&clock)); fprintf(fp, "### bsddialog theme - %s", ctime(&clock));
fputs("# Refer to bsddialog(3) manual for theme.* properties\n", fp); fputs("# Refer to bsddialog(3) manual for theme.* properties\n", fp);
@ -167,11 +169,15 @@ int savetheme(const char *file, char *errbuf, const char *version)
} }
fclose(fp); fclose(fp);
return (BSDDIALOG_OK);
} }
int loadtheme(const char *file, char *errbuf) void setdeftheme(enum bsddialog_default_theme theme)
{
if (bsddialog_set_default_theme(theme) != BSDDIALOG_OK)
EXIT_FMTERROR("%s", bsddialog_geterror());
}
void loadtheme(const char *file)
{ {
bool boolvalue; bool boolvalue;
char charvalue, *value; char charvalue, *value;
@ -181,21 +187,16 @@ int loadtheme(const char *file, char *errbuf)
enum bsddialog_color bg, fg; enum bsddialog_color bg, fg;
FILE *fp; FILE *fp;
if (bsddialog_get_theme(&t) != BSDDIALOG_OK) { if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
sprintf(errbuf, "Cannot get current theme: %s", EXIT_FMTERROR("Cannot get current theme: %s",
bsddialog_geterror()); bsddialog_geterror());
return (BSDDIALOG_ERROR);
}
if((fp = fopen(file, "r")) == NULL) { if((fp = fopen(file, "r")) == NULL)
sprintf(errbuf, "Cannot open theme \"%s\"", file); EXIT_FMTERROR("Cannot open theme \"%s\"", file);
return (BSDDIALOG_ERROR);
}
#define RETURN_ERROR(name, error) do { \ #define EXIT_ERROR(name, error) do { \
sprintf(errbuf, "%s for \"%s\"", error, name); \
fclose(fp); \ fclose(fp); \
return (BSDDIALOG_ERROR); \ EXIT_FMTERROR("%s for \"%s\"", error, name); \
} while (0) } while (0)
while(fgets(line, BUFSIZ, fp) != NULL) { while(fgets(line, BUFSIZ, fp) != NULL) {
@ -211,7 +212,7 @@ int loadtheme(const char *file, char *errbuf)
if (i >= NPROPERTY) { if (i >= NPROPERTY) {
if (strcmp(name, "version") == 0) if (strcmp(name, "version") == 0)
continue; continue;
RETURN_ERROR(name, "Unknown theme property name"); EXIT_ERROR(name, "Unknown theme property name");
} }
switch (p[i].type) { switch (p[i].type) {
case CHAR: case CHAR:
@ -219,17 +220,17 @@ int loadtheme(const char *file, char *errbuf)
value[0] == '\0') value[0] == '\0')
value++; value++;
if (sscanf(value, "%c", &charvalue) != 1) if (sscanf(value, "%c", &charvalue) != 1)
RETURN_ERROR(p[i].name, "Cannot get a char"); EXIT_ERROR(p[i].name, "Cannot get a char");
*((int*)p[i].value) = charvalue; *((int*)p[i].value) = charvalue;
break; break;
case INT: case INT:
if (sscanf(value, "%d", &intvalue) != 1) if (sscanf(value, "%d", &intvalue) != 1)
RETURN_ERROR(p[i].name, "Cannot get a int"); EXIT_ERROR(p[i].name, "Cannot get a int");
*((int*)p[i].value) = intvalue; *((int*)p[i].value) = intvalue;
break; break;
case UINT: case UINT:
if (sscanf(value, "%u", &uintvalue) != 1) if (sscanf(value, "%u", &uintvalue) != 1)
RETURN_ERROR(p[i].name, "Cannot get a uint"); EXIT_ERROR(p[i].name, "Cannot get a uint");
*((unsigned int*)p[i].value) = uintvalue; *((unsigned int*)p[i].value) = uintvalue;
break; break;
case BOOL: case BOOL:
@ -239,19 +240,19 @@ int loadtheme(const char *file, char *errbuf)
break; break;
case COLOR: case COLOR:
if (sscanf(value, "%s %s", c1, c2) != 2) if (sscanf(value, "%s %s", c1, c2) != 2)
RETURN_ERROR(p[i].name, "Cannot get 2 colors"); EXIT_ERROR(p[i].name, "Cannot get 2 colors");
/* Foreground */ /* Foreground */
for (j = 0; j < 8 ; j++) for (j = 0; j < 8 ; j++)
if ((strstr(c1, color[j])) != NULL) if ((strstr(c1, color[j])) != NULL)
break; break;
if ((fg = j) > 7) if ((fg = j) > 7)
RETURN_ERROR(p[i].name, "Bad foreground"); EXIT_ERROR(p[i].name, "Bad foreground");
/* Background */ /* Background */
for (j = 0; j < 8 ; j++) for (j = 0; j < 8 ; j++)
if ((value = strstr(c2, color[j])) != NULL) if ((value = strstr(c2, color[j])) != NULL)
break; break;
if ((bg = j) > 7) if ((bg = j) > 7)
RETURN_ERROR(p[i].name, "Bad background"); EXIT_ERROR(p[i].name, "Bad background");
/* Flags */ /* Flags */
flags = 0; flags = 0;
if (strstr(value, "bold") != NULL) if (strstr(value, "bold") != NULL)
@ -268,11 +269,9 @@ int loadtheme(const char *file, char *errbuf)
fclose(fp); fclose(fp);
bsddialog_set_theme(&t); bsddialog_set_theme(&t);
return (BSDDIALOG_OK);
} }
int bikeshed(struct bsddialog_conf *conf, char *errbuf) void bikeshed(struct bsddialog_conf *conf)
{ {
int margin, i; int margin, i;
int colors[8] = {0, 0, 0, 0 ,0 ,0 , 0, 0}; int colors[8] = {0, 0, 0, 0 ,0 ,0 , 0, 0};
@ -284,7 +283,7 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
/* theme */ /* theme */
if (bsddialog_get_theme(&t) != BSDDIALOG_OK) if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
return (BSDDIALOG_ERROR); EXIT_FMTERROR("%s", bsddialog_geterror());
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
do { do {
@ -339,7 +338,7 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0); t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0);
if (bsddialog_set_theme(&t)) if (bsddialog_set_theme(&t))
return (BSDDIALOG_ERROR); EXIT_FMTERROR("%s", bsddialog_geterror());
/* conf */ /* conf */
conf->button.always_active = (rand() % 2 == 0) ? true : false; conf->button.always_active = (rand() % 2 == 0) ? true : false;
@ -351,6 +350,4 @@ int bikeshed(struct bsddialog_conf *conf, char *errbuf)
memset(title + strlen(title), ' ', margin); memset(title + strlen(title), ' ', margin);
conf->title = title; conf->title = title;
} }
return (BSDDIALOG_OK);
} }

View File

@ -28,8 +28,9 @@
#ifndef _BSDDIALOG_UTILITY_THEME_H_ #ifndef _BSDDIALOG_UTILITY_THEME_H_
#define _BSDDIALOG_UTILITY_THEME_H_ #define _BSDDIALOG_UTILITY_THEME_H_
int savetheme(const char *file, char *errbuf, const char *version); void savetheme(const char *file, const char *version);
int loadtheme(const char *file, char *errbuf); void loadtheme(const char *file);
int bikeshed(struct bsddialog_conf *conf, char *errbuf); void setdeftheme(enum bsddialog_default_theme theme);
void bikeshed(struct bsddialog_conf *conf);
#endif #endif

View File

@ -6,6 +6,7 @@ LIB= bsddialog
PRIVATELIB= yes PRIVATELIB= yes
SHLIB_MAJOR= 0 SHLIB_MAJOR= 0
SRCS= barbox.c \ SRCS= barbox.c \
calendarbox.c \
formbox.c \ formbox.c \
infobox.c \ infobox.c \
lib_util.c \ lib_util.c \

View File

@ -5,8 +5,6 @@ PROG= bsddialog
SRCS= bsddialog.c util_theme.c SRCS= bsddialog.c util_theme.c
MAN= bsddialog.1 MAN= bsddialog.1
CFLAGS+= -I${BSDDIALOG}/lib CFLAGS+= -I${BSDDIALOG}/lib
LIBADD= bsddialog LIBADD= bsddialog tinfow
WARNS= 3
.include <bsd.prog.mk> .include <bsd.prog.mk>