mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-26 20:12:44 +00:00
bsddialog: import version 1.0
This commit is contained in:
commit
61ba55bcf7
2
contrib/bsddialog/.gitignore
vendored
2
contrib/bsddialog/.gitignore
vendored
@ -12,8 +12,10 @@ examples_library/calendar
|
||||
examples_library/checklist
|
||||
examples_library/datebox
|
||||
examples_library/form
|
||||
examples_library/gauge
|
||||
examples_library/infobox
|
||||
examples_library/menu
|
||||
examples_library/mixedgauge
|
||||
examples_library/mixedlist
|
||||
examples_library/msgbox
|
||||
examples_library/pause
|
||||
|
@ -1,3 +1,173 @@
|
||||
2023-08-01 Version 1.0
|
||||
|
||||
Utility:
|
||||
* add: comments to --save-theme output file.
|
||||
* add: blink, halfbright, highlight to --save-theme and --load-theme.
|
||||
* add: theme.menu.[f_]prefixcolor to --save-theme and --load-theme.
|
||||
* add: --datebox-format <d/m/y|m/d/y|y/m/d> to set --datebox UI.
|
||||
* add: --help-print-items (--help-status becomes alias).
|
||||
* add: --text-escape (--colors becomes alias).
|
||||
* add: new escapes \Zd, \Zk, \Zs, \ZD, \ZK, \ZS, for --text-escape.
|
||||
* add: env NO_COLOR, to set blackwhite theme.
|
||||
* add: $HOME/.bsddialog.conf startup theme file.
|
||||
* add: env BSDDIALOG_THEMEFILE startup theme file.
|
||||
* add: --left1-button <label>.
|
||||
* add: --left2-button <label>.
|
||||
* add: --left3-button <label>.
|
||||
* add: --right1-button <label>.
|
||||
* add: --right2-button <label>.
|
||||
* add: --right3-button <label>.
|
||||
* add: dynamic exit codes.
|
||||
- add: --error-exit-code.
|
||||
- add: --ok-exit-code.
|
||||
- add: --cancel-exit-code.
|
||||
- add: --help-exit-code.
|
||||
- add: --extra-exit-code.
|
||||
- add: --timeout-exit-code.
|
||||
- add: --esc-exit-code.
|
||||
- add: --left1-exit-code.
|
||||
- add: --left2-exit-code.
|
||||
- add: --left3-exit-code.
|
||||
- add: --right1-exit-code.
|
||||
- add: --right2-exit-code.
|
||||
- add: --right3-exit-code.
|
||||
- add: env BSDDIALOG_ERROR.
|
||||
- add: env BSDDIALOG_OK.
|
||||
- add: env BSDDIALOG_CANCEL.
|
||||
- add: env BSDDIALOG_HELP.
|
||||
- add: env BSDDIALOG_EXTRA.
|
||||
- add: env BSDDIALOG_TIMEOUT.
|
||||
- add: env BSDDIALOG_ESC.
|
||||
- add: env BSDDIALOG_LEFT1.
|
||||
- add: env BSDDIALOG_LEFT2.
|
||||
- add: env BSDDIALOG_LEFT3.
|
||||
- add: env BSDDIALOG_RIGHT1.
|
||||
- add: env BSDDIALOG_RIGHT2.
|
||||
- add: env BSDDIALOG_RIGHT3.
|
||||
* add: undocumented envs for bsdconfig(8) compatibility.
|
||||
- env BSDDIALOG_COMPATRC for use_shadow setting.
|
||||
- env BSDDIALOG_ITEM_HELP to add/set exit code.
|
||||
* change: rename themes --theme <3d|blackwhite|flat>.
|
||||
* change: --no-names and --no-descriptions mutually exclusive (via lia).
|
||||
* change: quote only checklist output items if necessary. Previously
|
||||
also radiolist item.
|
||||
* change: dialogs with user input print always values except with ERROR,
|
||||
ESC, Cancel. Previously the situation was quite heterogeneous.
|
||||
* improve: DIAGNOSTIC messages adding fmt string errors.
|
||||
* improve: disable theme setting (opt and env) with no-color terminals.
|
||||
* improve: menus on|off status (strcasecmp, diagnostic, real off check).
|
||||
* improve: --bikeshed with button delimiter and --date-format.
|
||||
* improve: --textbox accepts button options.
|
||||
* improve: Forms with Help button.
|
||||
- print "HELP" (like menus).
|
||||
- accept --help-list-items.
|
||||
- accept --help-print-name.
|
||||
* fix: --load-theme attributes.
|
||||
* fix: --clear-screen with --and-dialog.
|
||||
* delete: --theme <bsddialog> (partially implemented).
|
||||
* delete: --esc-return-cancel (replaced by new env and option).
|
||||
* delete: --generic-button1 (replaced by --right1-button).
|
||||
* delete: --generic-button2 (replaced by --right2-button).
|
||||
* refactor: modularize in more files (main, cli, builders, theme).
|
||||
|
||||
Library:
|
||||
* add: bsddialog_inmode().
|
||||
* add: bsddialog_clear(y) for utility --clear-screen.
|
||||
* add: bsddialog_refresh() for utility terminal mode options.
|
||||
* add: conf.date.format="d/m/y"|"m/d/y"|"y/m/d" to customize
|
||||
bsddialog_datebox() UI (boxes) with a date format.
|
||||
* add: 'const char *end' to bsddialog_gauge().
|
||||
* add: draw focus on the shortcut-key-selected button at exit.
|
||||
* add: escapes for conf.text.highlight \Zd, \Zk, \Zs, \ZD, \ZK, \ZS.
|
||||
* add: other theme flags.
|
||||
- BSDDIALOG_BLINK.
|
||||
- BSDDIALOG_HALFBRIGHT.
|
||||
- BSDDIALOG_HIGHLIGHT.
|
||||
* add: generic buttons.
|
||||
- conf.button.left1_label, BSDDIALOG_LEFT1 return value.
|
||||
- conf.button.left2_label, BSDDIALOG_LEFT2 return value.
|
||||
- conf.button.left3_label, BSDDIALOG_LEFT3 return value.
|
||||
- conf.button.right1.label, BSDDIALOG_RIGHT1 return value.
|
||||
- conf.button.right2.label, BSDDIALOG_RIGHT2 return value.
|
||||
- conf.button.right3.label, BSDDIALOG_RIGHT3 return value.
|
||||
* add: unused bsddialog_menugroup.min_on for future features.
|
||||
* add: theme.menu.f_prefixcolor and theme.menu.prefixcolor.
|
||||
* improve: check (when possible) API pointers.
|
||||
* improve: circolar buttons with left and right keys for msgbox, yesno,
|
||||
menus, rangebox and pause.
|
||||
* improve: bsddialog_textbox() handles conf.buttons.
|
||||
* improve: bsddialog_datebox() a box change affects the others as well.
|
||||
* improve: bsddialog_geterror() with fmt strings.
|
||||
* change: API NULL strings handled like "", except gauge *sep and *end.
|
||||
* change: menus and form less restrictive with text, hide text with
|
||||
little screens (same behavior as other dialogs).
|
||||
* change: mixedgauge BSDDIALOG_MG_BLANK does not draw minibar but prints
|
||||
minilabel. The change allows mixedgauge to add sections. To restore
|
||||
the previous behavior setting minilabel to "".
|
||||
* change: check/set bsddialog_gauge() perc max 100.
|
||||
* change: check/set bsddialog_mixedgauge() mainperc max 100.
|
||||
* change: conf.menu.no_name and conf.menu.no_desc mutually exclusive.
|
||||
* change: bsddialog_pause() sec -> *sec to know remaining time at exit.
|
||||
* change: add *focusitem to bsddialog_form() like menus.
|
||||
* change: "pointer" values are always set except when BSDDIALOG_ERROR
|
||||
occurs. Examples *yy/*mm/*ss, rangebox *value.
|
||||
- delete conf.menu.on_without_ok.
|
||||
- delete conf.form.value_without_ok.
|
||||
* rename: conf.text.highlight -> conf.text.escape.
|
||||
* rename: theme.menu.namesepcolor -> theme.menu.sepnamecolor.
|
||||
* rename: theme.menu.descsepcolor -> theme.menu.sepdesccolor.
|
||||
* fix: bsddialog_pause() elevation bar after resize.
|
||||
* fix: bsddialog_textbox() key '0'.
|
||||
* fix: timebox.c checksize (boxes width).
|
||||
* fix: extend menurows after shrink and enlarge.
|
||||
* fix: menu pad and form pad "re-expansion" after shrink and enlarge.
|
||||
* fix: shadow top-left corner (trick wresize() before wmove()).
|
||||
* fix: increment bsddialog_total_progview size for more general use.
|
||||
* delete: BSDDIALOG_THEME_BSDDIALOG (partially implemented).
|
||||
* delete: conf.button.generic1_label (for new conf.button.right1_label).
|
||||
* delete: BSDDIALOG_GENERIC1 return value (new BSDDIALOG_RIGHT1).
|
||||
* delete: conf.button.generic2_label (for new conf.button.right2_label).
|
||||
* delete: BSDDIALOG_GENERIC2 return value (new BSDDIALOG_RIGHT2).
|
||||
* delete: bsddialog_clearterminal(), replaced by bsddialog_clear(y).
|
||||
* refactor: internal implementation.
|
||||
- add: internal structures to represent components.
|
||||
- merge: (when possible) dialogs autosize.
|
||||
- merge: (when possible) dialogs checksize.
|
||||
- merge: for each dialog "build" with "update" -> <dialog>_redraw().
|
||||
- merge: new_dialog() with update_dialog() -> draw_dialog().
|
||||
- merge: infobox.c with messagebox.c (delete infobox.c)
|
||||
- merge: bsddialog_datebox() + bsddialog_calendar() -> datebox.c
|
||||
- change: flat and blackwhite real themes, 3d adapted from flat.
|
||||
- improve: replace wrefresh() -> wnoutrefresh()/doupdate().
|
||||
- improve: replace prefresh() -> pnoutrefresh()/doupdate().
|
||||
- improve: menu split code to build private items.
|
||||
- improve: form split code to build private items.
|
||||
- delete: -Wno-implicit-fallthrough.
|
||||
|
||||
|
||||
2023-06-12 Version 0.4.2
|
||||
|
||||
Library:
|
||||
* fix: compile error with aarch64-gcc12 for "\Z[0-7]" check;
|
||||
https://gitlab.com/alfix/bsddialog/-/issues/5.
|
||||
* fix: BSDDIALOG_FIELDCURSOREND with multiple items
|
||||
(warning aarch64-gcc12).
|
||||
|
||||
|
||||
2023-01-02 Version 0.4.1
|
||||
|
||||
Utility:
|
||||
* fix: default space separator menus output, except if --separator " ".
|
||||
* rename: GNUMakefile to GNUmakefile to simplify linux build.
|
||||
Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/2.
|
||||
|
||||
Library:
|
||||
* fix: t.dialog.linelowercolor no bold-black, some terminal draws grey.
|
||||
* fix: text wrapping (actual string length) with --colors.
|
||||
* rename: GNUMakefile to GNUmakefile to simplify linux build.
|
||||
Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/2.
|
||||
|
||||
|
||||
2022-09-24 Version 0.4
|
||||
|
||||
Utility:
|
||||
@ -6,19 +176,19 @@
|
||||
* 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: --no-names (--no-tags becomes alias).
|
||||
* add: --no-descriptions (--no-items becomes alias).
|
||||
* add: --help-print-name (--help-tags becomes alias).
|
||||
* add: --item-bottom-desc (--item-help becomes 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: --tab-escape to enable "\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: --clear becomes alias for --clear-screen.
|
||||
* change: --print-maxsize format output.
|
||||
* change: --menu, --radiolist, --checklist and --treeview output.
|
||||
- no printed items with Cancel or ESC.
|
||||
@ -41,9 +211,9 @@
|
||||
* 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).
|
||||
* change: fixed-menurows becomes at most menurows (depending on text).
|
||||
* change: fixed-rows becomes at most rows, min(rows, screenH - shadow).
|
||||
* change: fixed-cols becomes at most cols, min(cols, screenW - shadow).
|
||||
* delete: undocumented internal bsddialog_menuitem.depth factor (was 2).
|
||||
|
||||
|
||||
@ -55,9 +225,9 @@
|
||||
* add: --load-theme to read and set a custom theme at runtime.
|
||||
* add: --save-theme to save current theme.
|
||||
* add: --bikeshed for random settings.
|
||||
* add: --switch-buttons enables focus switching: buttons / input
|
||||
components. Available for: --form, --inputbox, --mixedform,
|
||||
--passwordform, --passwordbox, --timebox and --datebox.
|
||||
* add: --switch-buttons to enable buttons/input widgets focus switching.
|
||||
Available for: --form, --inputbox, --mixedform, --passwordform,
|
||||
--passwordbox, --timebox and --datebox.
|
||||
* change: rename --esc-cancelvalue to --esc-return-cancel.
|
||||
* change: form field value is printed like multibyte charachter string,
|
||||
previously widechar string.
|
||||
|
@ -1,28 +0,0 @@
|
||||
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT= bsddialog
|
||||
SOURCES= bsddialog.c util_theme.c
|
||||
OBJECTS= $(SOURCES:.c=.o)
|
||||
LIBPATH= ./lib
|
||||
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
|
||||
CFLAGS= -Wall -Wextra -I$(LIBPATH)
|
||||
LDFLAGS= -ltinfo -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
|
||||
RM = rm -f
|
||||
|
||||
all : $(OUTPUT)
|
||||
|
||||
$(OUTPUT): $(LIBBSDDIALOG) $(OBJECTS)
|
||||
$(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
${LIBBSDDIALOG}:
|
||||
make -C ${LIBPATH} -f GNUMakefile
|
||||
|
||||
%.o: %.c $(LIBBSDDIALOG)
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
make -C ${LIBPATH} -f GNUMakefile clean
|
||||
$(RM) $(OUTPUT) *.o *~
|
@ -1,6 +1,6 @@
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2021-2022, Alfonso Sabato Siciliano
|
||||
Copyright (c) 2021-2023, 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,50 +1,38 @@
|
||||
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
# Written in 2023 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT= bsddialog
|
||||
SOURCES= bsddialog.c util_theme.c
|
||||
OBJECTS= ${SOURCES:.c=.o}
|
||||
LIBPATH= ${.CURDIR}/lib
|
||||
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
|
||||
OUTPUT = bsddialog
|
||||
export VERSION=1.0
|
||||
.CURDIR ?= ${CURDIR}
|
||||
LIBPATH = ${.CURDIR}/lib
|
||||
LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so
|
||||
UTILITYPATH = ${.CURDIR}/utility
|
||||
|
||||
CFLAGS+= -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror
|
||||
# `make -DDEBUG`
|
||||
.if defined(DEBUG)
|
||||
CFLAGS= -g -Wall -I${LIBPATH}
|
||||
LIBDEBUG= -DDEBUG
|
||||
.endif
|
||||
LDFLAGS+= -ltinfow -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
|
||||
|
||||
BINDIR= /usr/local/bin
|
||||
MAN= ${OUTPUT}.1
|
||||
GZIP= gzip -cn
|
||||
MANDIR= /usr/local/share/man/man1
|
||||
|
||||
INSTALL= install
|
||||
RM= rm -f
|
||||
LN = ln -s -f
|
||||
|
||||
### cli options ###
|
||||
# port/pkg Makefile: 'MAKE_ARGS = -DNORPATH'
|
||||
NORPATH ?=
|
||||
export DISABLERPATH=${NORPATH}
|
||||
# `make -DDEBUG`
|
||||
# `gmake DEBUG=1`
|
||||
DEBUG ?=
|
||||
export ENABLEDEBUG=${DEBUG}
|
||||
|
||||
all : ${OUTPUT}
|
||||
|
||||
${OUTPUT}: ${LIBBSDDIALOG} ${OBJECTS}
|
||||
${CC} ${LDFLAGS} ${OBJECTS} -o ${.PREFIX}
|
||||
${OUTPUT}: ${LIBBSDDIALOG}
|
||||
${MAKE} -C ${UTILITYPATH} LIBPATH=${LIBPATH}
|
||||
${LN} ${UTILITYPATH}/${OUTPUT} ${.CURDIR}/${OUTPUT}
|
||||
|
||||
${LIBBSDDIALOG}:
|
||||
make -C ${LIBPATH} ${LIBDEBUG}
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} -s -m 555 ${OUTPUT} ${BINDIR}
|
||||
${GZIP} ${MAN} > ${MAN}.gz
|
||||
${INSTALL} -m 444 ${MAN}.gz ${MANDIR}
|
||||
|
||||
unistall:
|
||||
${RM} ${BINDIR}/${OUTPUT}
|
||||
${RM} ${MANDIR}/${MAN}.gz
|
||||
${MAKE} -C ${LIBPATH}
|
||||
|
||||
clean:
|
||||
make -C ${LIBPATH} clean
|
||||
${RM} ${OUTPUT} *.o *~ *.core ${MAN}.gz
|
||||
${MAKE} -C ${LIBPATH} clean
|
||||
${MAKE} -C ${UTILITYPATH} clean
|
||||
${RM} ${OUTPUT} *.core
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
# BSDDialog 0.4
|
||||
# BSDDialog 1.0
|
||||
|
||||
This project provides **bsddialog** and **libbsddialog**, an utility
|
||||
and a library to build scripts and tools with TUI dialogs and widgets.
|
||||
|
||||
|
||||
## Demo
|
||||
|
||||
[Screenshots](https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074).
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
FreeBSD:
|
||||
FreeBSD and Linux:
|
||||
|
||||
```
|
||||
% git clone https://gitlab.com/alfix/bsddialog.git
|
||||
@ -16,15 +20,6 @@ FreeBSD:
|
||||
% ./bsddialog --msgbox "Hello World!" 8 20
|
||||
```
|
||||
|
||||
Linux:
|
||||
|
||||
```
|
||||
% git clone https://gitlab.com/alfix/bsddialog.git
|
||||
% cd bsddialog
|
||||
% make -f GNUMakefile
|
||||
% ./bsddialog --msgbox "Hello World!" 8 20
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
![screenshot](screenshot.png)
|
||||
@ -60,6 +55,7 @@ in the _Public Domain_ to build new projects:
|
||||
```
|
||||
% sh ./examples_utility/calendar.sh
|
||||
% sh ./examples_utility/checklist.sh
|
||||
% sh ./examples_utility/datebox.sh
|
||||
% sh ./examples_utility/form.sh
|
||||
% sh ./examples_utility/gauge.sh
|
||||
% sh ./examples_utility/infobox.sh
|
||||
@ -72,6 +68,7 @@ in the _Public Domain_ to build new projects:
|
||||
% sh ./examples_utility/passwordform.sh
|
||||
% sh ./examples_utility/pause.sh
|
||||
% sh ./examples_utility/radiolist.sh
|
||||
% sh ./examples_utility/rangebox.sh
|
||||
% sh ./examples_utility/timebox.sh
|
||||
% sh ./examples_utility/yesno.sh
|
||||
```
|
||||
@ -100,8 +97,10 @@ in the _Public Domain_ to build new projects:
|
||||
% ./checklist
|
||||
% ./datebox
|
||||
% ./form
|
||||
% ./gauge
|
||||
% ./infobox
|
||||
% ./menu
|
||||
% ./mixedgauge
|
||||
% ./mixedlist
|
||||
% ./msgbox
|
||||
% ./pause
|
||||
@ -114,7 +113,19 @@ in the _Public Domain_ to build new projects:
|
||||
|
||||
|
||||
## TODO and Ideas
|
||||
|
||||
|
||||
- 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
|
||||
- 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.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
int main()
|
||||
@ -31,25 +30,16 @@ int main()
|
||||
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;
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return (output);
|
||||
printf("Date: %u/%u/%u\n", yy, mm, dd);
|
||||
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -28,27 +27,19 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "checklist";
|
||||
output = bsddialog_checklist(&conf, "Example", 15, 30, 5, 5, items,
|
||||
NULL);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_CANCEL) {
|
||||
printf("Cancel\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
printf("Checklist:\n");
|
||||
for (i = 0; i < 5; i++)
|
||||
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
|
||||
libpath=../lib
|
||||
examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
|
||||
datebox form timebox rangebox pause calendar"
|
||||
datebox form timebox rangebox pause calendar gauge mixedgauge"
|
||||
|
||||
rm -f $examples
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
int main()
|
||||
@ -31,25 +30,15 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "datebox";
|
||||
output = bsddialog_datebox(&conf, "Example", 9, 35, &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;
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
printf("\n");
|
||||
printf("Date: %u/%u/%u\n", yy, mm, dd);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define H BSDDIALOG_FIELDHIDDEN
|
||||
#define RO BSDDIALOG_FIELDREADONLY
|
||||
@ -37,23 +36,17 @@ int main()
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "form";
|
||||
conf.form.securech = '*';
|
||||
output = bsddialog_form(&conf, "Example", 10, 50, 3, 3, items);
|
||||
output = bsddialog_form(&conf, "Example", 10, 50, 3, 3, items, NULL);
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_CANCEL) {
|
||||
printf("Cancel\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
printf("%s \"%s\"\n", items[i].label, items[i].value);
|
||||
free(items[i].value);
|
||||
}
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
||||
|
57
contrib/bsddialog/examples_library/gauge.c
Normal file
57
contrib/bsddialog/examples_library/gauge.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Written in 2023 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 <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void sender(int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= 10; i++) {
|
||||
sleep(1);
|
||||
dprintf(fd, "SEP\n");
|
||||
dprintf(fd, "%d\n", i * 10);
|
||||
dprintf(fd, "In Progress... [%d / 10]\n", i);
|
||||
dprintf(fd, "SEP\n");
|
||||
}
|
||||
sleep(1);
|
||||
dprintf(fd, "EOF\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int rv, fd[2];
|
||||
struct bsddialog_conf conf;
|
||||
|
||||
/* add checks and sync */
|
||||
pipe(fd);
|
||||
if (fork() == 0) {
|
||||
close(fd[0]);
|
||||
sender(fd[1]);
|
||||
exit (0);
|
||||
}
|
||||
close(fd[1]);
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "gauge";
|
||||
rv = bsddialog_gauge(&conf, "Example", 7, 30, 0, fd[0], "SEP", "EOF");
|
||||
bsddialog_end();
|
||||
if(rv == BSDDIALOG_ERROR)
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -21,18 +20,15 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "infobox";
|
||||
conf.sleep = 3;
|
||||
output = bsddialog_infobox(&conf, "Example\n(3 seconds)", 7, 20);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -28,26 +27,18 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "menu";
|
||||
output = bsddialog_menu(&conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_CANCEL) {
|
||||
printf("Cancel\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
printf("Menu:\n");
|
||||
for (i = 0; i < 5; i++)
|
||||
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
79
contrib/bsddialog/examples_library/mixedgauge.c
Normal file
79
contrib/bsddialog/examples_library/mixedgauge.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Written in 2023 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NMINIBAR 13
|
||||
|
||||
static const char *minilabels[NMINIBAR] = {
|
||||
"Label 1",
|
||||
"Label 2",
|
||||
"Label 3",
|
||||
"Label 4",
|
||||
"Label 5",
|
||||
"Label 6",
|
||||
"Label 7",
|
||||
"Label 8",
|
||||
"Label 9",
|
||||
"Label 10",
|
||||
"Label 11",
|
||||
"Label X",
|
||||
"Label Y",
|
||||
};
|
||||
|
||||
static int minipercs[NMINIBAR] = {
|
||||
BSDDIALOG_MG_SUCCEEDED,
|
||||
BSDDIALOG_MG_FAILED,
|
||||
BSDDIALOG_MG_PASSED,
|
||||
BSDDIALOG_MG_COMPLETED,
|
||||
BSDDIALOG_MG_CHECKED,
|
||||
BSDDIALOG_MG_DONE,
|
||||
BSDDIALOG_MG_SKIPPED,
|
||||
BSDDIALOG_MG_INPROGRESS,
|
||||
BSDDIALOG_MG_BLANK,
|
||||
BSDDIALOG_MG_NA,
|
||||
BSDDIALOG_MG_PENDING,
|
||||
67,
|
||||
0,
|
||||
};
|
||||
|
||||
static void exit_error()
|
||||
{
|
||||
if (bsddialog_inmode())
|
||||
bsddialog_end();
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int retval, i;
|
||||
struct bsddialog_conf conf;
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR)
|
||||
exit_error();
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "mixedgauge";
|
||||
for (i = 0; i <= 10; i++) {
|
||||
minipercs[11] += 3;
|
||||
minipercs[12] = i * 10;
|
||||
retval= bsddialog_mixedgauge(&conf, "Example", 20, 40,
|
||||
50 + i * 5, NMINIBAR, minilabels, minipercs);
|
||||
if(retval == BSDDIALOG_ERROR)
|
||||
exit_error();
|
||||
sleep(1);
|
||||
}
|
||||
bsddialog_end();
|
||||
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -40,34 +39,26 @@ int main()
|
||||
{ "", false, 0, "Name 5", "Desc 5", "Bottom Desc 5" }
|
||||
};
|
||||
struct bsddialog_menugroup group[4] = {
|
||||
{ BSDDIALOG_SEPARATOR, 1, sep1 },
|
||||
{ BSDDIALOG_CHECKLIST, 5, check },
|
||||
{ BSDDIALOG_SEPARATOR, 2, sep2 },
|
||||
{ BSDDIALOG_RADIOLIST, 5, radio }
|
||||
{ BSDDIALOG_SEPARATOR, 1, sep1, 0 },
|
||||
{ BSDDIALOG_CHECKLIST, 5, check, 0 },
|
||||
{ BSDDIALOG_SEPARATOR, 2, sep2, 0 },
|
||||
{ BSDDIALOG_RADIOLIST, 5, radio, 0 }
|
||||
};
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "mixedlist";
|
||||
output = bsddialog_mixedlist(&conf, "Example", 20, 0, 13, 4, group,
|
||||
NULL, NULL);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_CANCEL) {
|
||||
printf("Cancel\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
printf("Mixedlist:\n");
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < group[i].nitems; j++) {
|
||||
@ -83,5 +74,5 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -21,21 +20,19 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "msgbox";
|
||||
output = bsddialog_msgbox(&conf, "Example", 7, 20);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
switch (output) {
|
||||
case BSDDIALOG_ERROR:
|
||||
printf("Error %s\n", bsddialog_geterror());
|
||||
break;
|
||||
return (1);
|
||||
case BSDDIALOG_OK:
|
||||
printf("OK\n");
|
||||
printf("[OK]\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,38 +10,37 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int output;
|
||||
unsigned int sec;
|
||||
struct bsddialog_conf conf;
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "pause";
|
||||
output = bsddialog_pause(&conf, "Example", 8, 50, 10);
|
||||
|
||||
sec = 10;
|
||||
output = bsddialog_pause(&conf, "Example", 8, 50, &sec);
|
||||
bsddialog_end();
|
||||
|
||||
switch (output) {
|
||||
case BSDDIALOG_OK:
|
||||
printf("OK\n");
|
||||
break;
|
||||
case BSDDIALOG_CANCEL:
|
||||
printf("Cancel\n");
|
||||
break;
|
||||
case BSDDIALOG_ERROR:
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
case BSDDIALOG_OK:
|
||||
printf("[OK] remaining time: %u\n", sec);
|
||||
break;
|
||||
case BSDDIALOG_CANCEL:
|
||||
printf("[Cancel] remaining time: %u\n", sec);
|
||||
break;
|
||||
case BSDDIALOG_TIMEOUT:
|
||||
printf("Timeout\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -28,26 +27,19 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "radiolist";
|
||||
output = bsddialog_radiolist(&conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||
|
||||
output = bsddialog_radiolist(&conf, "Example", 15, 30, 5, 5, items,
|
||||
NULL);
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_CANCEL) {
|
||||
printf("Cancel\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
printf("Radiolist:\n");
|
||||
for (i = 0; i < 5; i++)
|
||||
printf(" (%c) %s\n", items[i].on ? '*' : ' ', items[i].name);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -21,20 +20,16 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "rangebox";
|
||||
value = 5;
|
||||
output = bsddialog_rangebox(&conf, "Example", 8, 50, 0, 10, &value);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf("Value: %d\n", value);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -11,64 +11,54 @@
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int output, focusitem;
|
||||
struct bsddialog_conf conf;
|
||||
enum bsddialog_default_theme theme;
|
||||
struct bsddialog_menuitem items[5] = {
|
||||
{"", false, 0, "Flat", "dialog-like",
|
||||
"BSDDIALOG_THEME_FLAT" },
|
||||
{"", false, 0, "Dialog", "dialog clone",
|
||||
"BSDDIALOG_THEME_DIALOG" },
|
||||
{"", false, 0, "BSDDialog", "new theme",
|
||||
"BSDDIALOG_THEME_BSDDIALOG" },
|
||||
{"", false, 0, "BlackWhite","black and white",
|
||||
"BSDDIALOG_THEME_BLACKWHITE" },
|
||||
{"", false, 0, "Quit", "Exit", "Quit or Cancel to exit" }
|
||||
struct bsddialog_menuitem items[4] = {
|
||||
{"", false, 0, "Flat", "default flat theme",
|
||||
"enum bsddialog_default_theme BSDDIALOG_THEME_FLAT" },
|
||||
{"", false, 0, "3D", "pseudo 3D theme",
|
||||
"enum bsddialog_default_theme BSDDIALOG_THEME_3D" },
|
||||
{"", false, 0, "BlackWhite","black and white theme",
|
||||
"enum bsddialog_default_theme BSDDIALOG_THEME_BLACKWHITE" },
|
||||
{"", false, 0, "Quit", "Exit", "Quit, Cancel or ESC to exit" }
|
||||
};
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
|
||||
conf.ascii_lines = true;
|
||||
bsddialog_backtitle(&conf, "Theme Example");
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.key.enable_esc = true;
|
||||
conf.title = " Theme ";
|
||||
focusitem = -1;
|
||||
while (true) {
|
||||
output = bsddialog_menu(&conf, "Choose theme", 15, 45, 5, 5,
|
||||
output = bsddialog_menu(&conf, "Choose theme", 15, 45, 4, 4,
|
||||
items, &focusitem);
|
||||
|
||||
if (output != BSDDIALOG_OK || items[4].on)
|
||||
if (output != BSDDIALOG_OK || items[3].on)
|
||||
break;
|
||||
|
||||
if (items[0].on) {
|
||||
theme = BSDDIALOG_THEME_FLAT;
|
||||
focusitem = 0;
|
||||
}
|
||||
else if (items[1].on) {
|
||||
theme = BSDDIALOG_THEME_DIALOG;
|
||||
} else if (items[1].on) {
|
||||
theme = BSDDIALOG_THEME_3D;
|
||||
focusitem = 1;
|
||||
}
|
||||
else if (items[2].on) {
|
||||
theme = BSDDIALOG_THEME_BSDDIALOG;
|
||||
} else if (items[2].on) {
|
||||
theme = BSDDIALOG_THEME_BLACKWHITE;
|
||||
focusitem = 2;
|
||||
}
|
||||
else if (items[3].on) {
|
||||
theme = BSDDIALOG_THEME_BLACKWHITE;
|
||||
focusitem = 3;
|
||||
}
|
||||
|
||||
bsddialog_set_default_theme(theme);
|
||||
}
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
int main()
|
||||
@ -31,24 +30,15 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "timebox";
|
||||
output = bsddialog_timebox(&conf, "Example", 9, 35, &hh, &mm, &ss);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
switch (output) {
|
||||
case BSDDIALOG_OK:
|
||||
printf("Time: [%u:%u:%u]\n", hh, mm, ss);
|
||||
break;
|
||||
case BSDDIALOG_CANCEL:
|
||||
printf("Cancel\n");
|
||||
break;
|
||||
case BSDDIALOG_ERROR:
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
break;
|
||||
return (1);
|
||||
}
|
||||
printf("Time: %u:%u:%u\n", hh, mm, ss);
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -21,24 +20,22 @@ int main()
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "yesno";
|
||||
output = bsddialog_yesno(&conf, "Example", 7, 25);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
switch (output) {
|
||||
case BSDDIALOG_ERROR:
|
||||
printf("Error %s\n", bsddialog_geterror());
|
||||
break;
|
||||
return (1);
|
||||
case BSDDIALOG_YES:
|
||||
printf("YES\n");
|
||||
printf("[YES]\n");
|
||||
break;
|
||||
case BSDDIALOG_NO:
|
||||
printf("NO\n");
|
||||
printf("[NO]\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return (output);
|
||||
return (0);
|
||||
}
|
@ -15,11 +15,11 @@
|
||||
: ${BSDDIALOG_ESC=5}
|
||||
|
||||
ITEMS=$(./bsddialog --title " checklist " --checklist "Hello World!" 15 30 5 \
|
||||
"Tag 1" "DESC 1 xyz" on \
|
||||
"Tag 2" "DESC 2 xyz" off \
|
||||
"Tag 3" "DESC 3 xyz" on \
|
||||
"Tag 4" "DESC 4 xyz" off \
|
||||
"Tag 5" "DESC 5 xyz" on \
|
||||
"1 Name" "DESC 1 xyz" on \
|
||||
"2 Name" "DESC 2 xyz" off \
|
||||
"3 Name" "DESC 3 xyz" on \
|
||||
"4 Name" "DESC 4 xyz" off \
|
||||
"5 Name" "DESC 5 xyz" on \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
@ -27,12 +27,12 @@ case $? in
|
||||
exit 1
|
||||
;;
|
||||
$BSDDIALOG_ESC )
|
||||
echo "[ESC] focus: $ITEMS"
|
||||
echo "[ESC]"
|
||||
;;
|
||||
$BSDDIALOG_CANCEL )
|
||||
echo "[Cancel] focus: $ITEMS"
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK] Selected: $ITEMS"
|
||||
echo "[OK] $ITEMS"
|
||||
;;
|
||||
esac
|
||||
|
34
contrib/bsddialog/examples_utility/datebox.sh
Executable file
34
contrib/bsddialog/examples_utility/datebox.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
#-
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Written in 2023 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 " datebox " --date-format "%x" \
|
||||
--datebox "Hello World!" 9 30 \
|
||||
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
|
@ -33,8 +33,6 @@ case $? in
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $FORMS"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$FORMS"
|
||||
|
@ -9,4 +9,4 @@
|
||||
# worldwide. This software is distributed without any warranty, see:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
./bsddialog --sleep 3 --title " infobox " --infobox "Hello World!\n3 secs" 6 20
|
||||
./bsddialog --normal-screen --title " infobox " --infobox "Hello World!" 6 20
|
||||
|
@ -28,9 +28,6 @@ case $? in
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $FORM"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$FORM"
|
||||
|
||||
|
@ -15,10 +15,11 @@
|
||||
: ${BSDDIALOG_ESC=5}
|
||||
|
||||
ITEM=$(./bsddialog --title " menu " --menu "Hello World!" 15 30 5 \
|
||||
"Tag 1" "DESC 1 xyz" \
|
||||
"Tag 2" "DESC 2 xyz" \
|
||||
"Tag 3" "DESC 3 xyz" \
|
||||
"Tag 4" "DESC 4 xyz" \
|
||||
"1 Name" "DESC 1 xyz" \
|
||||
"2 Name" "DESC 2 xyz" \
|
||||
"3 Name" "DESC 3 xyz" \
|
||||
"4 Name" "DESC 4 xyz" \
|
||||
"5 Name" "DESC 5 xyz" \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
@ -26,10 +27,10 @@ case $? in
|
||||
exit 1
|
||||
;;
|
||||
$BSDDIALOG_ESC )
|
||||
echo "[ESC] $ITEM"
|
||||
echo "[ESC]"
|
||||
;;
|
||||
$BSDDIALOG_CANCEL )
|
||||
echo "[Cancel] $ITEM"
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK] $ITEM"
|
||||
|
@ -32,8 +32,6 @@ case $? in
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $FORMS"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$FORMS"
|
||||
|
@ -10,11 +10,11 @@
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
perc=0
|
||||
mainperc=50
|
||||
while [ $perc -le 100 ]
|
||||
do
|
||||
./bsddialog --sleep 1 --title " mixedgauge " \
|
||||
--mixedgauge "Example..." 20 45 $perc \
|
||||
"(Hidden)" " -9" \
|
||||
--mixedgauge "Example..." 20 45 $mainperc \
|
||||
"Label 1" " -1" \
|
||||
"Label 2" " -2" \
|
||||
"Label 3" " -3" \
|
||||
@ -23,9 +23,11 @@ do
|
||||
"Label 6" " -6" \
|
||||
"Label 7" " -7" \
|
||||
"Label 8" " -8" \
|
||||
"Label 9" " -10" \
|
||||
"Label 10" " -11" \
|
||||
"Label 9" " -9" \
|
||||
"Label 10" " -10" \
|
||||
"Label 11" " -11" \
|
||||
"Label X" $perc
|
||||
|
||||
perc=`expr $perc + 20`
|
||||
mainperc=`expr $mainperc + 10`
|
||||
done
|
||||
|
@ -29,8 +29,6 @@ case $? in
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $FORM"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$FORM"
|
||||
|
@ -34,8 +34,6 @@ case $? in
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $FORMS"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$FORMS"
|
||||
|
@ -15,11 +15,11 @@
|
||||
: ${BSDDIALOG_ESC=5}
|
||||
|
||||
ITEM=$(./bsddialog --title " radiolist " --radiolist "Hello World!" 15 30 5 \
|
||||
"Tag 1" "DESC 1 xyz" off \
|
||||
"Tag 2" "DESC 2 xyz" off \
|
||||
"Tag 3" "DESC 3 xyz" on \
|
||||
"Tag 4" "DESC 4 xyz" off \
|
||||
"Tag 5" "DESC 5 xyz" off \
|
||||
"1 Name" "DESC 1 xyz" off \
|
||||
"2 Name" "DESC 2 xyz" off \
|
||||
"3 Name" "DESC 3 xyz" on \
|
||||
"4 Name" "DESC 4 xyz" off \
|
||||
"5 Name" "DESC 5 xyz" off \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
@ -27,14 +27,12 @@ case $? in
|
||||
exit 1
|
||||
;;
|
||||
$BSDDIALOG_ESC )
|
||||
echo "[ESC] focus "
|
||||
echo "[ESC]"
|
||||
;;
|
||||
$BSDDIALOG_CANCEL )
|
||||
echo "[Cancel] focus "
|
||||
echo "[Cancel]"
|
||||
;;
|
||||
$BSDDIALOG_OK )
|
||||
echo "[OK]"
|
||||
echo "[OK] $ITEM"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$ITEM"
|
||||
|
33
contrib/bsddialog/examples_utility/rangebox.sh
Normal file
33
contrib/bsddialog/examples_utility/rangebox.sh
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
#-
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Written in 2023 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}
|
||||
|
||||
VALUE=$(./bsddialog --title " rangebox " --rangebox "Hello World!" 7 35 0 10 5 \
|
||||
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] Value: $VALUE"
|
||||
;;
|
||||
esac
|
@ -3,16 +3,19 @@
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
VERSION = 0.4
|
||||
LIBRARY = bsddialog
|
||||
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
|
||||
SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
|
||||
lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
|
||||
SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \
|
||||
menubox.c messagebox.c textbox.c theme.c timebox.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra \
|
||||
-Wno-implicit-fallthrough -Werror -fpic
|
||||
LDFLAGS = -lncursesw -ltinfo
|
||||
|
||||
ifneq ($(ENABLEDEBUG),)
|
||||
CFLAGS += -g
|
||||
endif
|
||||
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE \
|
||||
-Wall -Wextra -Werror -fpic
|
||||
LDFLAGS += -lncursesw -ltinfo
|
||||
LIBFLAG = -shared
|
||||
|
||||
RM = rm -f
|
@ -3,39 +3,27 @@
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
VERSION = 0.4
|
||||
LIBRARY = bsddialog
|
||||
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||
LIBRARY_A = lib${LIBRARY:=.a}
|
||||
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
|
||||
SOURCES = barbox.c calendarbox.c formbox.c infobox.c libbsddialog.c \
|
||||
lib_util.c menubox.c messagebox.c textbox.c theme.c timebox.c
|
||||
SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \
|
||||
menubox.c messagebox.c textbox.c theme.c timebox.c
|
||||
OBJECTS = ${SOURCES:.c=.o}
|
||||
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra
|
||||
|
||||
.if defined(DEBUG)
|
||||
CFLAGS += -g
|
||||
.endif
|
||||
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra -std=gnu99 \
|
||||
-fstack-protector-strong
|
||||
LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
|
||||
-Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION} \
|
||||
-L/usr/lib -lncursesw -ltinfow
|
||||
|
||||
.if defined(DEBUG)
|
||||
# `make -DDEBUG`
|
||||
CFLAGS = -g -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra
|
||||
.else
|
||||
CFLAGS += -std=gnu99 -fstack-protector-strong
|
||||
.endif
|
||||
|
||||
LOCALBASE = /usr/local
|
||||
LN = ln -s -f
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
GZIP = gzip -cn
|
||||
LDCONFIG = /sbin/ldconfig -m
|
||||
MAN = ${OUTPUT}.3
|
||||
GZIP = gzip -cn
|
||||
MANDIR = ${LOCALBASE}/share/man/man3
|
||||
INSTALL = install
|
||||
RM = rm -f
|
||||
|
||||
all : man ${LIBRARY}
|
||||
all : ${LIBRARY}
|
||||
|
||||
${LIBRARY}: ${LIBRARY_SO} ${LIBRARY_A}
|
||||
|
||||
@ -52,24 +40,5 @@ ${LIBRARY_A}: ${OBJECTS}
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
man:
|
||||
${GZIP} ${LIBRARY}.3 > ${LIBRARY}.3.gz
|
||||
|
||||
clean:
|
||||
${RM} ${LIBRARY_SO}* *.o *~ *.gz ${LIBRARY_A}
|
||||
|
||||
|
||||
install:
|
||||
${INSTALL} -m 644 ${HEADERS} ${LOCALBASE}/include
|
||||
${INSTALL} -m 644 -s ${LIBRARY_SO}.${VERSION} ${LOCALBASE}/lib/
|
||||
${INSTALL} -l rs ${LOCALBASE}/lib/${LIBRARY_SO}.${VERSION} ${LOCALBASE}/lib/${LIBRARY_SO}
|
||||
${INSTALL} -m 644 ${LIBRARY_A} ${LOCALBASE}/lib
|
||||
${LDCONFIG} ${LOCALBASE}/lib
|
||||
${INSTALL} -m 644 ${LIBRARY}.3.gz ${MANDIR}
|
||||
|
||||
unistall:
|
||||
${RM} ${LOCALBASE}/include/${LIBRARY}*.h
|
||||
${RM} ${LOCALBASE}/lib/${LIBRARY_SO}
|
||||
${RM} ${LOCALBASE}/lib/${LIBRARY_SO}.${VERSION}
|
||||
${LDCONFIG} ${LOCALBASE}/lib
|
||||
${RM} ${MANDIR}/${LIBRARY}.3.gz
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,9 +25,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -39,139 +36,138 @@
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
#define BARPADDING 2
|
||||
#define MINBARLEN 15
|
||||
#define MINBARWIDTH (2 + 2 * BARPADDING + MINBARLEN)
|
||||
#define MINMGBARLEN 18
|
||||
#define MINMGBARWIDTH (2 + 2 * BARPADDING + MINMGBARLEN)
|
||||
#define BARPADDING 2 /* widget 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_WMGBOX (BARPADDING + BOXBORDERS + MIN_WMGBAR + BARPADDING)
|
||||
#define HBOX 3
|
||||
#define WBOX(d) ((d)->w - BORDERS - BARPADDING - BARPADDING)
|
||||
#define WBAR(d) (WBOX(d) - BOXBORDERS)
|
||||
|
||||
bool bsddialog_interruptprogview;
|
||||
bool bsddialog_abortprogview;
|
||||
int bsddialog_total_progview;
|
||||
long long int bsddialog_total_progview;
|
||||
|
||||
static void
|
||||
draw_bar(WINDOW *win, int y, int x, int barlen, int perc, bool withlabel,
|
||||
int label)
|
||||
static const char states[12][14] = {
|
||||
" Succeeded ", /* -1 */
|
||||
" Failed ", /* -2 */
|
||||
" Passed ", /* -3 */
|
||||
" Completed ", /* -4 */
|
||||
" Checked ", /* -5 */
|
||||
" Done ", /* -6 */
|
||||
" Skipped ", /* -7 */
|
||||
" In Progress ", /* -8 */
|
||||
"(blank) ", /* -9 */
|
||||
" N/A ", /* -10 */
|
||||
" Pending ", /* -11 */
|
||||
" UNKNOWN ", /* < -11, no API */
|
||||
};
|
||||
|
||||
struct bar {
|
||||
bool toupdate;
|
||||
WINDOW *win;
|
||||
int y; /* bar y in win */
|
||||
int x; /* bar x in win */
|
||||
int w; /* width in win */
|
||||
int perc; /* barlen = (w * perc) / 100 */
|
||||
const char* fmt; /* format for label */
|
||||
int label; /* rangebox and pause perc!=label */
|
||||
};
|
||||
|
||||
static void draw_bar(struct bar *b)
|
||||
{
|
||||
int i, blue_x, color, stringlen;
|
||||
char labelstr[128];
|
||||
int barlen, xlabel;
|
||||
chtype ch;
|
||||
char label[128];
|
||||
|
||||
blue_x = perc > 0 ? (perc * barlen) / 100 : -1;
|
||||
barlen = b->perc > 0 ? (b->perc * b->w) / 100 : 0;
|
||||
|
||||
wmove(win, y, x);
|
||||
for (i = 0; i < barlen; i++) {
|
||||
color = (i <= blue_x) ? t.bar.f_color : t.bar.color;
|
||||
wattron(win, color);
|
||||
waddch(win, ' ');
|
||||
wattroff(win, color);
|
||||
}
|
||||
ch = ' ' | t.bar.f_color;
|
||||
mvwhline(b->win, b->y, b->x, ch, barlen);
|
||||
ch = ' ' | t.bar.color;
|
||||
mvwhline(b->win, b->y, b->x + barlen, ch, b->w - barlen);
|
||||
|
||||
if (withlabel)
|
||||
sprintf(labelstr, "%d", label);
|
||||
else
|
||||
sprintf(labelstr, "%3d%%", perc);
|
||||
stringlen = (int)strlen(labelstr); /* number, always 1-byte-ch string */
|
||||
wmove(win, y, x + barlen/2 - stringlen/2);
|
||||
for (i = 0; i < stringlen; i++) {
|
||||
color = (blue_x + 1 <= barlen/2 - stringlen/2 + i ) ?
|
||||
t.bar.color : t.bar.f_color;
|
||||
wattron(win, color);
|
||||
waddch(win, labelstr[i]);
|
||||
wattroff(win, color);
|
||||
}
|
||||
sprintf(label, b->fmt, b->label);
|
||||
xlabel = b->x + b->w/2 - (int)strlen(label)/2; /* 1-byte-char string */
|
||||
wattron(b->win, t.bar.color); /* x+barlen < xlabel */
|
||||
mvwaddstr(b->win, b->y, xlabel, label);
|
||||
wattroff(b->win, t.bar.color);
|
||||
wattron(b->win, t.bar.f_color); /* x+barlen >= xlabel */
|
||||
mvwaddnstr(b->win, b->y, xlabel, label, MAX((b->x+barlen) - xlabel, 0));
|
||||
wattroff(b->win, t.bar.f_color);
|
||||
|
||||
if (b->toupdate)
|
||||
wnoutrefresh(b->win);
|
||||
b->toupdate = false;
|
||||
}
|
||||
|
||||
static int
|
||||
bar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
|
||||
const char *text, struct buttons *bs)
|
||||
static void update_barbox(struct dialog *d, struct bar *b, bool buttons)
|
||||
{
|
||||
int htext, wtext;
|
||||
int y;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, bs, 3, MINBARWIDTH,
|
||||
&htext, &wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, wtext, MINBARWIDTH, bs);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 3 /* bar */, bs != NULL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bar_checksize(int rows, int cols, struct buttons *bs)
|
||||
{
|
||||
int minheight, minwidth;
|
||||
|
||||
minwidth = 0;
|
||||
if (bs != NULL) /* gauge has not buttons */
|
||||
minwidth = buttons_min_width(*bs);
|
||||
|
||||
minwidth = MAX(minwidth, MINBARWIDTH);
|
||||
minwidth += VBORDERS;
|
||||
|
||||
if (cols < minwidth)
|
||||
RETURN_ERROR("Few cols to draw bar and/or buttons");
|
||||
|
||||
minheight = HBORDERS + 3;
|
||||
if (bs != NULL)
|
||||
minheight += 2;
|
||||
if (rows < minheight)
|
||||
RETURN_ERROR("Few rows to draw bar");
|
||||
|
||||
return (0);
|
||||
y = d->y + d->h - BORDER - HBOX;
|
||||
if (buttons)
|
||||
y -= HBUTTONS;
|
||||
update_box(d->conf, b->win, y, d->x + BORDER + BARPADDING, HBOX,
|
||||
WBOX(d), RAISED);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int perc, int fd, const char *sep)
|
||||
int cols, unsigned int perc, int fd, const char *sep, const char *end)
|
||||
{
|
||||
bool mainloop;
|
||||
int y, x, h, w, fd2;
|
||||
int fd2;
|
||||
FILE *input;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
char inputbuf[2048], ntext[2048], *pntext;
|
||||
struct bar b;
|
||||
struct dialog d;
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_autosize(conf, rows, cols, &h, &w, text, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_checksize(h, w, NULL) != 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, NULL,
|
||||
false) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED);
|
||||
if ((b.win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW bar");
|
||||
b.y = b.x = 1;
|
||||
b.fmt = "%3d%%";
|
||||
|
||||
input = NULL;
|
||||
if (fd >= 0) {
|
||||
CHECK_PTR(sep);
|
||||
CHECK_PTR(end);
|
||||
|
||||
fd2 = dup(fd);
|
||||
if ((input = fdopen(fd2, "r")) == NULL)
|
||||
RETURN_ERROR("Cannot build FILE* from fd");
|
||||
RETURN_FMTERROR("Cannot build FILE* from fd %d", fd);
|
||||
}
|
||||
|
||||
perc = MIN(perc, 100);
|
||||
mainloop = true;
|
||||
while (mainloop) {
|
||||
wrefresh(widget);
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-4,
|
||||
x+w-1-TEXTHMARGIN);
|
||||
draw_borders(conf, bar, 3, w-6, RAISED);
|
||||
draw_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
|
||||
wrefresh(bar);
|
||||
if (d.built) {
|
||||
hide_dialog(&d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(&d, HBOX, MIN_WBOX, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(&d))
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d.built)
|
||||
refresh(); /* fix grey lines expanding screen */
|
||||
TEXTPAD(&d, HBOX);
|
||||
update_barbox(&d, &b, false);
|
||||
b.w = WBAR(&d);
|
||||
b.perc = b.label = perc;
|
||||
b.toupdate = true;
|
||||
draw_bar(&b);
|
||||
doupdate();
|
||||
if (input == NULL) /* that is fd < 0 */
|
||||
break;
|
||||
|
||||
while (true) {
|
||||
fscanf(input, "%s", inputbuf);
|
||||
if (strcmp(inputbuf,"EOF") == 0) {
|
||||
if (strcmp(inputbuf, end) == 0) {
|
||||
mainloop = false;
|
||||
break;
|
||||
}
|
||||
@ -181,12 +177,12 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
if (mainloop == false)
|
||||
break;
|
||||
fscanf(input, "%d", &perc);
|
||||
perc = perc > 100 ? 100 : perc;
|
||||
perc = MIN(perc, 100);
|
||||
pntext = &ntext[0];
|
||||
ntext[0] = '\0';
|
||||
while (true) {
|
||||
fscanf(input, "%s", inputbuf);
|
||||
if (strcmp(inputbuf,"EOF") == 0) {
|
||||
if (strcmp(inputbuf, end) == 0) {
|
||||
mainloop = false;
|
||||
break;
|
||||
}
|
||||
@ -198,15 +194,13 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
pntext++;
|
||||
}
|
||||
pntext[0] = '\0';
|
||||
if (update_dialog(conf, shadow, widget, y, x, h, w, textpad,
|
||||
ntext, NULL, false) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
d.text = ntext;
|
||||
}
|
||||
|
||||
if (input != NULL)
|
||||
fclose(input);
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
delwin(b.win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
@ -217,120 +211,95 @@ 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, retval, miniperc, y, x, h, w, ypad, max_minbarlen;
|
||||
int htextpad, htext, wtext;
|
||||
int colorperc, red, green;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
char states[12][14] = {
|
||||
" Succeeded ", /* -1 */
|
||||
" Failed ", /* -2 */
|
||||
" Passed ", /* -3 */
|
||||
" Completed ", /* -4 */
|
||||
" Checked ", /* -5 */
|
||||
" Done ", /* -6 */
|
||||
" Skipped ", /* -7 */
|
||||
" In Progress ", /* -8 */
|
||||
"(blank) ", /* -9 */
|
||||
" N/A ", /* -10 */
|
||||
" Pending ", /* -11 */
|
||||
" UNKNOWN ", /* < -11, no API */
|
||||
};
|
||||
int i, miniperc, max_minibarlen;
|
||||
int ystext, htext;
|
||||
int minicolor, red, green;
|
||||
struct bar b;
|
||||
struct dialog d;
|
||||
|
||||
CHECK_ARRAY(nminibars, minilabels);
|
||||
CHECK_ARRAY(nminibars, minipercs);
|
||||
|
||||
red = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED, BSDDIALOG_BOLD);
|
||||
green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
|
||||
|
||||
max_minbarlen = 0;
|
||||
max_minibarlen = 0;
|
||||
for (i = 0; i < (int)nminibars; i++)
|
||||
max_minbarlen = MAX(max_minbarlen, (int)strcols(minilabels[i]));
|
||||
max_minbarlen += 3 + 16; /* seps + [...] */
|
||||
max_minbarlen = MAX(max_minbarlen, MINMGBARWIDTH); /* mainbar */
|
||||
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 (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
/* mixedgauge autosize */
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, NULL, nminibars + 3,
|
||||
max_minbarlen, &htext, &wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
w = widget_min_width(conf, wtext, max_minbarlen, NULL);
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
h = widget_min_height(conf, htext, nminibars + 3, false);
|
||||
|
||||
/* mixedgauge checksize */
|
||||
if (w < max_minbarlen + 2)
|
||||
RETURN_ERROR("Few cols for this mixedgauge");
|
||||
if (h < 5 + (int)nminibars)
|
||||
RETURN_ERROR("Few rows for this mixedgauge");
|
||||
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
if (dialog_size_position(&d, nminibars + HBOX, max_minibarlen,
|
||||
&htext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(&d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
retval = new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
|
||||
NULL, false);
|
||||
if (retval == BSDDIALOG_ERROR)
|
||||
return (retval);
|
||||
|
||||
/* mini bars */
|
||||
b.win = d.widget;
|
||||
b.x = 1 + d.w - 2 - 15;
|
||||
b.w = 13;
|
||||
b.fmt = "%3d%%";
|
||||
b.toupdate = false;
|
||||
for (i = 0; i < (int)nminibars; i++) {
|
||||
miniperc = minipercs[i];
|
||||
/* label */
|
||||
if (color && miniperc >= 0)
|
||||
wattron(d.widget, A_BOLD);
|
||||
mvwaddstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]));
|
||||
if (color && miniperc >= 0)
|
||||
wattroff(d.widget, A_BOLD);
|
||||
/* perc */
|
||||
if (miniperc == BSDDIALOG_MG_BLANK)
|
||||
continue;
|
||||
/* label */
|
||||
if (color && (miniperc >= 0))
|
||||
wattron(widget, A_BOLD);
|
||||
mvwaddstr(widget, i+1, 2, minilabels[i]);
|
||||
if (color && (miniperc >= 0))
|
||||
wattroff(widget, A_BOLD);
|
||||
/* perc */
|
||||
if (miniperc < -11)
|
||||
mvwaddstr(widget, i+1, w-2-15, states[11]);
|
||||
else if (miniperc < 0) {
|
||||
mvwaddstr(widget, i+1, w-2-15, "[ ]");
|
||||
colorperc = -1;
|
||||
mvwaddstr(d.widget, i+1, d.w-2-15, "[ ]");
|
||||
if (miniperc >= 0) {
|
||||
b.y = i + 1;
|
||||
b.perc = b.label = MIN(miniperc, 100);
|
||||
draw_bar(&b);
|
||||
} else { /* miniperc < 0 */
|
||||
if (miniperc < BSDDIALOG_MG_PENDING)
|
||||
miniperc = -12; /* UNKNOWN */
|
||||
minicolor = t.dialog.color;
|
||||
if (color && miniperc == BSDDIALOG_MG_FAILED)
|
||||
colorperc = red;
|
||||
if (color && miniperc == BSDDIALOG_MG_DONE)
|
||||
colorperc = green;
|
||||
if (colorperc != -1)
|
||||
wattron(widget, colorperc);
|
||||
minicolor = red;
|
||||
else if (color && miniperc == BSDDIALOG_MG_DONE)
|
||||
minicolor = green;
|
||||
wattron(d.widget, minicolor);
|
||||
miniperc = abs(miniperc + 1);
|
||||
mvwaddstr(widget, i+1, 1+w-2-15, states[miniperc]);
|
||||
if (colorperc != -1)
|
||||
wattroff(widget, colorperc);
|
||||
}
|
||||
else { /* miniperc >= 0 */
|
||||
if (miniperc > 100)
|
||||
miniperc = 100;
|
||||
mvwaddstr(widget, i+1, w-2-15, "[ ]");
|
||||
draw_bar(widget, i+1, 1+w-2-15, 13, miniperc, false,
|
||||
-1 /*unused*/);
|
||||
mvwaddstr(d.widget, i+1, 1+d.w-2-15, states[miniperc]);
|
||||
wattroff(d.widget, minicolor);
|
||||
}
|
||||
}
|
||||
wnoutrefresh(d.widget);
|
||||
|
||||
wrefresh(widget);
|
||||
getmaxyx(textpad, htextpad, i /* unused */);
|
||||
ypad = y + h - 4 - htextpad;
|
||||
ypad = ypad < y+(int)nminibars ? y+(int)nminibars : ypad;
|
||||
prefresh(textpad, 0, 0, ypad, x+2, y+h-4, x+w-2);
|
||||
/* text */
|
||||
ystext = MAX(d.h - BORDERS - htext - HBOX, (int)nminibars);
|
||||
rtextpad(&d, 0, 0, ystext, HBOX);
|
||||
|
||||
/* main bar */
|
||||
bar = new_boxed_window(conf, y+h -4, x+3, 3, w-6, RAISED);
|
||||
if ((b.win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW bar");
|
||||
update_barbox(&d, &b, false);
|
||||
wattron(b.win, t.bar.color);
|
||||
mvwaddstr(b.win, 0, 2, "Overall Progress");
|
||||
wattroff(b.win, t.bar.color);
|
||||
|
||||
draw_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/);
|
||||
b.y = b.x = 1;
|
||||
b.w = WBAR(&d);
|
||||
b.fmt = "%3d%%";
|
||||
b.perc = b.label = MIN(mainperc, 100);
|
||||
b.toupdate = true;
|
||||
draw_bar(&b);
|
||||
|
||||
wattron(bar, t.bar.color);
|
||||
mvwaddstr(bar, 0, 2, "Overall Progress");
|
||||
wattroff(bar, t.bar.color);
|
||||
doupdate();
|
||||
/* getch(); to test with "alternate mode" */
|
||||
|
||||
wrefresh(bar);
|
||||
|
||||
/* getch(); alternate mode (port devel/ncurses) shows nothing */
|
||||
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
delwin(b.win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
@ -414,7 +383,8 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
minipercs[i] = BSDDIALOG_MG_DONE;
|
||||
update = true;
|
||||
i++;
|
||||
} else if (minibar[i].status == BSDDIALOG_MG_FAILED || perc < 0) {
|
||||
} else if (minibar[i].status == BSDDIALOG_MG_FAILED ||
|
||||
perc < 0) {
|
||||
minipercs[i] = BSDDIALOG_MG_FAILED;
|
||||
update = true;
|
||||
} else /* perc >= 0 */
|
||||
@ -426,73 +396,73 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int rangebox_redraw(struct dialog *d, struct bar *b, int *bigchange)
|
||||
{
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
TEXTPAD(d, HBOX + HBUTTONS);
|
||||
|
||||
b->w = WBAR(d);
|
||||
*bigchange = MAX(1, b->w / 10);
|
||||
update_barbox(d, b, true);
|
||||
b->toupdate = true;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, int min, int max, int *value)
|
||||
{
|
||||
bool loop, buttupdate, barupdate;
|
||||
int y, x, h, w;
|
||||
int currvalue, retval, sizebar, bigchange, positions;
|
||||
bool loop;
|
||||
int currvalue, retval, bigchange, positions;
|
||||
wint_t input;
|
||||
float perc;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
struct buttons bs;
|
||||
|
||||
if (value == NULL)
|
||||
RETURN_ERROR("*value cannot be NULL");
|
||||
struct bar b;
|
||||
struct dialog d;
|
||||
|
||||
CHECK_PTR(value);
|
||||
if (min >= max)
|
||||
RETURN_ERROR("min >= max");
|
||||
RETURN_FMTERROR("min (%d) >= max (%d)", min, max);
|
||||
if (*value < min)
|
||||
RETURN_FMTERROR("value (%d) < min (%d)", *value, min);
|
||||
if (*value > max)
|
||||
RETURN_FMTERROR("value (%d) > max (%d)", *value, max);
|
||||
|
||||
currvalue = *value;
|
||||
positions = max - min + 1;
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_checksize(h, w, &bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
|
||||
if ((b.win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW bar");
|
||||
b.y = b.x = 1;
|
||||
b.fmt = "%d";
|
||||
if (rangebox_redraw(&d, &b, &bigchange) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
|
||||
true) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
doupdate();
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
|
||||
|
||||
sizebar = w - HBORDERS - (2 * BARPADDING) - 2;
|
||||
bigchange = MAX(1, sizebar/10);
|
||||
|
||||
bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
|
||||
sizebar + 2, RAISED);
|
||||
|
||||
loop = buttupdate = barupdate = true;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
if (buttupdate) {
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
buttupdate = false;
|
||||
if (b.toupdate) {
|
||||
b.perc = ((float)(currvalue - min)*100) / (positions-1);
|
||||
b.label = currvalue;
|
||||
draw_bar(&b);
|
||||
}
|
||||
if (barupdate) {
|
||||
perc = ((float)(currvalue - min)*100) / (positions-1);
|
||||
draw_bar(bar, 1, 1, sizebar, perc, true, currvalue);
|
||||
barupdate = false;
|
||||
wrefresh(bar);
|
||||
}
|
||||
|
||||
doupdate();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
retval = bs.value[bs.curr];
|
||||
*value = currvalue;
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
@ -502,159 +472,132 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
}
|
||||
break;
|
||||
case '\t': /* TAB */
|
||||
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||
buttupdate = true;
|
||||
case KEY_RIGHT:
|
||||
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (bs.curr > 0) {
|
||||
bs.curr--;
|
||||
buttupdate = true;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||
bs.curr++;
|
||||
buttupdate = true;
|
||||
}
|
||||
d.bs.curr--;
|
||||
if (d.bs.curr < 0)
|
||||
d.bs.curr = d.bs.nbuttons - 1;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_HOME:
|
||||
currvalue = max;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
break;
|
||||
case KEY_END:
|
||||
currvalue = min;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
currvalue -= bigchange;
|
||||
if (currvalue < min)
|
||||
currvalue = min;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
currvalue += bigchange;
|
||||
if (currvalue > max)
|
||||
currvalue = max;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (currvalue < max) {
|
||||
currvalue++;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (currvalue > min) {
|
||||
currvalue--;
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
}
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help(conf) != 0)
|
||||
if (f1help_dialog(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
/* No break, screen size can change */
|
||||
if (rangebox_redraw(&d, &b, &bigchange) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
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)
|
||||
if (rangebox_redraw(&d, &b, &bigchange) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_autosize(conf, rows, cols, &h, &w, text,
|
||||
&bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_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);
|
||||
|
||||
doupdate();
|
||||
|
||||
sizebar = w - HBORDERS - (2 * BARPADDING) - 2;
|
||||
bigchange = MAX(1, sizebar/10);
|
||||
wclear(bar);
|
||||
mvwin(bar, y + h - 6, x + 1 + BARPADDING);
|
||||
wresize(bar, 3, sizebar + 2);
|
||||
draw_borders(conf, bar, 3, sizebar+2, RAISED);
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
|
||||
x+w-1-TEXTHMARGIN);
|
||||
|
||||
barupdate = true;
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
retval = bs.value[bs.curr];
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
*value = currvalue;
|
||||
|
||||
delwin(b.win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int pause_redraw(struct dialog *d, struct bar *b)
|
||||
{
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
TEXTPAD(d, HBOX + HBUTTONS);
|
||||
|
||||
b->w = WBAR(d);
|
||||
update_barbox(d, b, true);
|
||||
b->toupdate = true;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int sec)
|
||||
int cols, unsigned int *seconds)
|
||||
{
|
||||
bool loop, buttupdate, barupdate;
|
||||
int retval, y, x, h, w, tout, sizebar;
|
||||
bool loop;
|
||||
int retval, tout;
|
||||
wint_t input;
|
||||
float perc;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
struct buttons bs;
|
||||
struct bar b;
|
||||
struct dialog d;
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
CHECK_PTR(seconds);
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_checksize(h, w, &bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
|
||||
if ((b.win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW bar");
|
||||
b.y = b.x = 1;
|
||||
b.fmt = "%d";
|
||||
if (pause_redraw(&d, &b) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
|
||||
true) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
doupdate();
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
|
||||
|
||||
sizebar = w - HBORDERS - (2 * BARPADDING) - 2;
|
||||
bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
|
||||
sizebar + 2, RAISED);
|
||||
|
||||
tout = sec;
|
||||
tout = *seconds;
|
||||
nodelay(stdscr, TRUE);
|
||||
timeout(1000);
|
||||
loop = buttupdate = barupdate = true;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
if (barupdate) {
|
||||
perc = (float)tout * 100 / sec;
|
||||
draw_bar(bar, 1, 1, sizebar, perc, true, tout);
|
||||
barupdate = false;
|
||||
wrefresh(bar);
|
||||
if (b.toupdate) {
|
||||
b.perc = (float)tout * 100 / *seconds;
|
||||
b.label = tout;
|
||||
draw_bar(&b);
|
||||
}
|
||||
|
||||
if (buttupdate) {
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
buttupdate = false;
|
||||
}
|
||||
|
||||
doupdate();
|
||||
if (get_wch(&input) == ERR) { /* timeout */
|
||||
tout--;
|
||||
if (tout < 0) {
|
||||
@ -662,14 +605,14 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
break;
|
||||
}
|
||||
else {
|
||||
barupdate = true;
|
||||
b.toupdate = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
retval = bs.value[bs.curr];
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
@ -679,72 +622,44 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
}
|
||||
break;
|
||||
case '\t': /* TAB */
|
||||
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||
buttupdate = true;
|
||||
case KEY_RIGHT:
|
||||
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (bs.curr > 0) {
|
||||
bs.curr--;
|
||||
buttupdate = true;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||
bs.curr++;
|
||||
buttupdate = true;
|
||||
}
|
||||
d.bs.curr--;
|
||||
if (d.bs.curr < 0)
|
||||
d.bs.curr = d.bs.nbuttons - 1;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help(conf) != 0)
|
||||
if (f1help_dialog(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
/* No break, screen size can change */
|
||||
if (pause_redraw(&d, &b) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
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)
|
||||
if (pause_redraw(&d, &b) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_autosize(conf, rows, cols, &h, &w, text,
|
||||
&bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (bar_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);
|
||||
|
||||
doupdate();
|
||||
|
||||
sizebar = w - HBORDERS - (2 * BARPADDING) - 2;
|
||||
wclear(bar);
|
||||
mvwin(bar, y + h - 6, x + 1 + BARPADDING);
|
||||
wresize(bar, 3, sizebar + 2);
|
||||
draw_borders(conf, bar, 3, sizebar+2, LOWERED);
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
|
||||
x+w-1-TEXTHMARGIN);
|
||||
|
||||
barupdate = true;
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
retval = bs.value[bs.curr];
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodelay(stdscr, FALSE);
|
||||
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
*seconds = MAX(tout, 0);
|
||||
|
||||
delwin(b.win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -22,13 +22,13 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 23, 2022
|
||||
.Dd July 28, 2023
|
||||
.Dt BSDDIALOG 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bsddialog_backtitle ,
|
||||
.Nm bsddialog_calendar ,
|
||||
.Nm bsddialog_clearterminal ,
|
||||
.Nm bsddialog_clear ,
|
||||
.Nm bsddialog_color ,
|
||||
.Nm bsddialog_color_attrs ,
|
||||
.Nm bsddialog_checklist ,
|
||||
@ -43,6 +43,7 @@
|
||||
.Nm bsddialog_init ,
|
||||
.Nm bsddialog_init_notheme ,
|
||||
.Nm bsddialog_initconf ,
|
||||
.Nm bsddialog_inmode ,
|
||||
.Nm bsddialog_menu ,
|
||||
.Nm bsddialog_mixedgauge ,
|
||||
.Nm bsddialog_mixedlist ,
|
||||
@ -50,6 +51,7 @@
|
||||
.Nm bsddialog_pause ,
|
||||
.Nm bsddialog_radiolist ,
|
||||
.Nm bsddialog_rangebox ,
|
||||
.Nm bsddialog_refresh ,
|
||||
.Nm bsddialog_set_theme ,
|
||||
.Nm bsddialog_set_default_theme ,
|
||||
.Nm bsddialog_textbox ,
|
||||
@ -68,9 +70,9 @@
|
||||
.Fa "const char *text"
|
||||
.Fa "int rows"
|
||||
.Fa "int cols"
|
||||
.Fa "unsigned int *yy"
|
||||
.Fa "unsigned int *mm"
|
||||
.Fa "unsigned int *dd"
|
||||
.Fa "unsigned int *year"
|
||||
.Fa "unsigned int *month"
|
||||
.Fa "unsigned int *day"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo bsddialog_checklist
|
||||
@ -83,17 +85,17 @@
|
||||
.Fa "struct bsddialog_menuitem *items"
|
||||
.Fa "int *focusitem"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn bsddialog_clearterminal "void"
|
||||
.Ft void
|
||||
.Fn bsddialog_clear "unsigned int y"
|
||||
.Ft int
|
||||
.Fo bsddialog_datebox
|
||||
.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"
|
||||
.Fa "unsigned int *year"
|
||||
.Fa "unsigned int *month"
|
||||
.Fa "unsigned int *day"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn bsddialog_end "void"
|
||||
@ -106,6 +108,7 @@
|
||||
.Fa "unsigned int formrows"
|
||||
.Fa "unsigned int nitems"
|
||||
.Fa "struct bsddialog_formitem *items"
|
||||
.Fa "int *focusitem"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo bsddialog_gauge
|
||||
@ -116,6 +119,7 @@
|
||||
.Fa "unsigned int perc"
|
||||
.Fa "int fd"
|
||||
.Fa "const char *sep"
|
||||
.Fa "const char *end"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fn bsddialog_geterror "void"
|
||||
@ -130,6 +134,8 @@
|
||||
.Fn bsddialog_init "void"
|
||||
.Ft int
|
||||
.Fn bsddialog_init_notheme "void"
|
||||
.Ft bool
|
||||
.Fn bsddialog_inmode "void"
|
||||
.Ft int
|
||||
.Fn bsddialog_initconf "struct bsddialog_conf *conf"
|
||||
.Ft int
|
||||
@ -179,7 +185,7 @@
|
||||
.Fa "const char *text"
|
||||
.Fa "int rows"
|
||||
.Fa "int cols"
|
||||
.Fa "unsigned int seconds"
|
||||
.Fa "unsigned int *seconds"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo bsddialog_radiolist
|
||||
@ -202,6 +208,8 @@
|
||||
.Fa "int max"
|
||||
.Fa "int *value"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn bsddialog_refresh "void"
|
||||
.Ft int
|
||||
.Fo bsddialog_textbox
|
||||
.Fa "struct bsddialog_conf *conf"
|
||||
@ -251,8 +259,7 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm bsddialog
|
||||
library provides an API to build Text User Interface dialogs and widgets: to
|
||||
display messages, to get input and to inform about a computation status.
|
||||
library provides an API to build Text User Interface dialogs and widgets.
|
||||
.Pp
|
||||
.Fn bsddialog_init
|
||||
initializes the library, the only functions that can be called before is
|
||||
@ -260,10 +267,7 @@ initializes the library, the only functions that can be called before is
|
||||
described later.
|
||||
After the initialization the input and output should be handled via the library
|
||||
API.
|
||||
.Fn bsddialog_end
|
||||
restores the screen like before
|
||||
.Fn bsddialog_init ,
|
||||
then it is not possible to use the library functions.
|
||||
.Pp
|
||||
.Fn bsddialog_init_notheme
|
||||
is equivalent to
|
||||
.Fn bsddialog_init
|
||||
@ -271,41 +275,64 @@ except it does not set the default graphical theme; see
|
||||
.Sx Theme
|
||||
subsection to set a theme explicitly.
|
||||
.Pp
|
||||
.Fn bsddialog_error
|
||||
returns a string to describe the last error, it should be called after a
|
||||
.Dv BSDDIALOG_ERROR
|
||||
returned value.
|
||||
.Fn bsddialog_clearterminal
|
||||
clears the screen.
|
||||
.Fn bsddialog_end
|
||||
restores the screen like before
|
||||
.Fn bsddialog_init .
|
||||
After the call is not possible to use the library functions.
|
||||
.Pp
|
||||
.Fn bsddialog_inmode
|
||||
returns
|
||||
.Dv true
|
||||
after
|
||||
.Fn bsddialog_init
|
||||
or
|
||||
.Fn bsddialog_init_notheme
|
||||
and before
|
||||
.Fn bsddialog_end ,
|
||||
.Dv false
|
||||
otherwise.
|
||||
.Pp
|
||||
.Fn bsddialog_backtitle
|
||||
prints
|
||||
.Fa backtitle
|
||||
on the top of the screen, it is possible to set
|
||||
on the top of the screen.
|
||||
The function handles
|
||||
.Fa conf.ascii_lines
|
||||
and
|
||||
.Fa conf.no_lines ;
|
||||
.Fa conf
|
||||
is described later.
|
||||
.Fa conf.no_lines
|
||||
described later.
|
||||
.Pp
|
||||
Each
|
||||
.Fa char*
|
||||
argument has to be a well terminated string, it can be a multibyte character
|
||||
string depending on current locale, see
|
||||
.Xr setlocale 3 .
|
||||
.Fn bsddialog_error
|
||||
returns a string to describe the last error.
|
||||
The function should be called after a
|
||||
.Dv BSDDIALOG_ERROR
|
||||
returned value.
|
||||
.Pp
|
||||
.Fn bsddialog_clear
|
||||
clears the screen from
|
||||
.Fa y .
|
||||
.Pp
|
||||
.Fn bsddialog_refresh
|
||||
useful to refresh the screen after a terminal mode change, see
|
||||
.Xr terminfo 5 .
|
||||
.Ss Dialogs
|
||||
The dialogs have common arguments.
|
||||
.Fa text
|
||||
is a string printed inside the dialog.
|
||||
Each
|
||||
.Fa char*
|
||||
parameter can be a multibyte character string depending on current locale, see
|
||||
.Xr setlocale 3 .
|
||||
.Fa rows
|
||||
and
|
||||
.Fa cols
|
||||
are height and width, their value can be between 2 and the screen size,
|
||||
are height and width, their value can be a fixed size,
|
||||
.Dv BSDDIALOG_AUTOSIZE
|
||||
or
|
||||
.Dv BSDDIALOG_FULLSCREEN .
|
||||
.Fa conf
|
||||
is a struct to customize the dialog, it does not set global properties to the
|
||||
library.
|
||||
is a struct to customize the current dialog, it does not set global properties
|
||||
to the library.
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
struct bsddialog_conf {
|
||||
@ -331,24 +358,28 @@ struct bsddialog_conf {
|
||||
} key;
|
||||
struct {
|
||||
unsigned int cols_per_row;
|
||||
bool highlight;
|
||||
bool escape;
|
||||
unsigned int tablen;
|
||||
} text;
|
||||
struct {
|
||||
bool align_left;
|
||||
bool no_desc;
|
||||
bool no_name;
|
||||
bool on_without_ok;
|
||||
bool shortcut_buttons;
|
||||
} menu;
|
||||
struct {
|
||||
char securech;
|
||||
char *securembch;
|
||||
bool value_wchar;
|
||||
bool value_without_ok;
|
||||
} form;
|
||||
struct {
|
||||
const char *format;
|
||||
} date;
|
||||
struct {
|
||||
bool always_active;
|
||||
const char *left1_label;
|
||||
const char *left2_label;
|
||||
const char *left3_label;
|
||||
bool without_ok;
|
||||
const char *ok_label;
|
||||
bool with_extra;
|
||||
@ -358,8 +389,9 @@ struct bsddialog_conf {
|
||||
bool default_cancel;
|
||||
bool with_help;
|
||||
const char *help_label;
|
||||
const char *generic1_label;
|
||||
const char *generic2_label;
|
||||
const char *right1_label;
|
||||
const char *right2_label;
|
||||
const char *right3_label;
|
||||
const char *default_label;
|
||||
} button;
|
||||
};
|
||||
@ -396,7 +428,7 @@ is
|
||||
or
|
||||
.Dv BSDDIALOG_FULLSCREEN .
|
||||
.It Fa conf.bottomtitle
|
||||
subtitle at the dialog bottom side.
|
||||
dialog subtitle.
|
||||
.It Fa conf.clear
|
||||
hide the dialog at exit.
|
||||
.It Fa conf.get_height
|
||||
@ -414,36 +446,35 @@ draw shadow.
|
||||
.It Fa conf.sleep
|
||||
wait before to return, the value is in seconds.
|
||||
.It Fa conf.title
|
||||
title at the top dialog side.
|
||||
dialog title.
|
||||
.It Fa conf.y
|
||||
vertical position, 0 is top screen size, can be
|
||||
dialog vertical position, 0 is top screen, can be
|
||||
.Dv BSDDIALOG_CENTER .
|
||||
.It Fa conf.x
|
||||
horizontal position, 0 is left screen side, can be
|
||||
dialog horizontal position, 0 is left screen, can be
|
||||
.Dv BSDDIALOG_CENTER .
|
||||
.El
|
||||
.Pp
|
||||
.Bl -column -compact
|
||||
.It Fa conf.key.enable_esc
|
||||
enables
|
||||
enable
|
||||
.Dv ESC
|
||||
key to close the dialog.
|
||||
.It Fa conf.key.f1_file
|
||||
file to open if F1 is pressed.
|
||||
open a file in a textbox if F1 is pressed.
|
||||
.It Fa conf.key.f1_message
|
||||
message to display if F1 is pressed.
|
||||
build a msgbox with message if F1 is pressed.
|
||||
.El
|
||||
.Pp
|
||||
.Bl -column -compact
|
||||
.It Fa conf.text.cols_per_row
|
||||
Try to set the number of columns for a row of
|
||||
.Fa text
|
||||
with autosizing; default
|
||||
with autosizing, default
|
||||
.Dv 10 .
|
||||
.It Fa conf.text.highlight
|
||||
enables highlights for
|
||||
.Fa text ,
|
||||
properly the following sequences are considered escapes:
|
||||
.It Fa conf.text.escape
|
||||
enable escapes in
|
||||
.Fa text :
|
||||
.It Dq \eZ0
|
||||
black.
|
||||
.It Dq \eZ1
|
||||
@ -460,14 +491,26 @@ magenta.
|
||||
cyan.
|
||||
.It Dq \eZ7
|
||||
white.
|
||||
.It Dq \eZr
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZb
|
||||
bold.
|
||||
.It Dq \eZB
|
||||
disable bold.
|
||||
.It Dq \eZd
|
||||
Half bright.
|
||||
.It Dq \eZD
|
||||
disable half bright.
|
||||
.It Dq \eZk
|
||||
Blink.
|
||||
.It Dq \eZK
|
||||
disable blinking.
|
||||
.It Dq \eZr
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZs
|
||||
Highlight.
|
||||
.It Dq \eZS
|
||||
disable highlighting.
|
||||
.It Dq \eZu
|
||||
underline.
|
||||
.It Dq \eZU
|
||||
@ -484,13 +527,19 @@ function.
|
||||
.Pp
|
||||
.Bl -column -compact
|
||||
.It Fa conf.button.always_active
|
||||
buttons always active, avoidind focus switch between buttons and input fields or
|
||||
buttons always active, avoiding focus switch between buttons and input fields or
|
||||
input boxes in
|
||||
.Fn bsddialog_form ,
|
||||
.Fn bsddialog_datebox ,
|
||||
.Fn bsddialog_calendar
|
||||
and
|
||||
.Fn bsddialog_timebox .
|
||||
.It Fa conf.button.left1_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.left2_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.left3_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.without_ok
|
||||
disable OK button.
|
||||
.It Fa conf.button.ok_label
|
||||
@ -509,9 +558,11 @@ on startup focus on the Cancel button.
|
||||
add Help button.
|
||||
.It Fa conf.button.help_label
|
||||
set a label for Help button.
|
||||
.It Fa conf.button.generic1_label
|
||||
.It Fa conf.button.right1_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.generic2_label
|
||||
.It Fa conf.button.right2_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.right3_label
|
||||
add a button with the specified label.
|
||||
.It Fa conf.button.default_label
|
||||
focus on the button with the specified label.
|
||||
@ -532,143 +583,35 @@ to
|
||||
to
|
||||
.Dv 10 .
|
||||
.Pp
|
||||
.Fn bsddialog_infobox
|
||||
builds a dialog without buttons and returns instantly.
|
||||
.Fn bsddialog_msgbox
|
||||
builds a dialog with OK button.
|
||||
.Fn bsddialog_yesno
|
||||
provides a dialog for a
|
||||
.Dq Yes-No Question ,
|
||||
the labels on buttons are Yes and No.
|
||||
.Pp
|
||||
.Fn bsddialog_pause
|
||||
builds a dialog waiting until the timeout in
|
||||
.Fa seconds
|
||||
expires or a button is pressed.
|
||||
.Pp
|
||||
.Fn bsddialog_calendar
|
||||
builds a dialog to select a date.
|
||||
.Fa year ,
|
||||
.Fa month ,
|
||||
and
|
||||
.Fn bsddialog_datebox
|
||||
build a dialog to select a date,
|
||||
.Fa yy ,
|
||||
.Fa mm ,
|
||||
and
|
||||
.Fa dd
|
||||
.Fa day
|
||||
are default values on startup, selected date at exit.
|
||||
.Fn bsddialog_timebox
|
||||
builds a dialog to choose a time,
|
||||
.Fa hh ,
|
||||
.Fa mm ,
|
||||
.Pp
|
||||
.Fn bsddialog_checklist
|
||||
builds dialogs to select some item from a list via the SPACE key, can be
|
||||
customized by
|
||||
.Fa conf.menu.* .
|
||||
See
|
||||
.Fn bsddialog_menu .
|
||||
.Pp
|
||||
.Fn bsddialog_datebox
|
||||
builds a dialog to select a date.
|
||||
.Fa year ,
|
||||
.Fa month ,
|
||||
and
|
||||
.Fa ss
|
||||
are default values on startup, selected time at exit.
|
||||
.Pp
|
||||
.Fn bsddialog_checklist ,
|
||||
.Fn bsddialog_menu
|
||||
and
|
||||
.Fn bsddialog_radiolist
|
||||
build dialogs to select some item from a list via the SPACE key, an item is
|
||||
defined like:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
struct bsddialog_menuitem {
|
||||
const char *prefix;
|
||||
bool on;
|
||||
unsigned int depth;
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *bottomdesc;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa prefix ,
|
||||
.Fa name
|
||||
and
|
||||
.Fa desc
|
||||
are strings to describe the item and are printed on its row,
|
||||
.Fa bottomdesc
|
||||
is printed on the bottom side of the screen,
|
||||
.Fa depth
|
||||
is a margin between the
|
||||
.Fa prefix
|
||||
and
|
||||
.Fa name
|
||||
useful to implement a
|
||||
.Dq treeview,
|
||||
.Fa on
|
||||
is set to
|
||||
.Dv true
|
||||
if the item is selected,
|
||||
.Dv false
|
||||
otherwise.
|
||||
.Fa items
|
||||
is an array of items of
|
||||
.Fa nitem
|
||||
elements,
|
||||
.Fa menurows
|
||||
specifies the graphical fixed height of the list, if
|
||||
.Fa cols
|
||||
is set to
|
||||
.Dv BSDDIALOG_AUTOSIZE
|
||||
.Fa menurows
|
||||
specifies a maximum value.
|
||||
Finally, if not
|
||||
.Dv NULL ,
|
||||
.Fa focusitem
|
||||
specifies the default item on startup and the last focused item at exit, could
|
||||
be a negative value if no item is focused.
|
||||
.Pp
|
||||
.Fn bsddialog_mixedlist
|
||||
builds a dialog with collections of checklists, radiolists and separators.
|
||||
A collection is a set defined like:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
enum bsddialog_menutype {
|
||||
BSDDIALOG_CHECKLIST,
|
||||
BSDDIALOG_RADIOLIST,
|
||||
BSDDIALOG_SEPARATOR,
|
||||
};
|
||||
|
||||
struct bsddialog_menugroup {
|
||||
enum bsddialog_menutype type;
|
||||
unsigned int nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa groups
|
||||
is an array of sets of
|
||||
.Fa ngroups
|
||||
elements.
|
||||
.Fa menurows
|
||||
is the graphical height size for the list.
|
||||
If not
|
||||
.Dv NULL ,
|
||||
.Fa focuslist
|
||||
and
|
||||
.Fa focusitem
|
||||
specify the default item on startup and the last focused item at exit, could be
|
||||
a negative value if no item is focused.
|
||||
.Pp
|
||||
.Fn bsddialog_checklist ,
|
||||
.Fn bsddialog_menu ,
|
||||
.Fn bsddialog_mixedlist
|
||||
and
|
||||
.Fn bsddialog_radiolist
|
||||
can be costomizated by:
|
||||
.Fa day
|
||||
are default values on startup, selected date at exit.
|
||||
The function can be customized by:
|
||||
.Bl -column -compact
|
||||
.It Fa conf.menu.align_left
|
||||
aligns items to left, default center.
|
||||
.It Fa conf.menu.no_desc
|
||||
hide description.
|
||||
.It Fa conf.menu.no_name
|
||||
hide names.
|
||||
.It Fa conf.menu.on_without_ok
|
||||
set items
|
||||
.Fa on
|
||||
also if the OK button is not pressed.
|
||||
.It Fa conf.menu.shortcut_buttons
|
||||
enable shortcut keys on buttons, default on items.
|
||||
.It Fa conf.date.format
|
||||
date format user interface, possible values:
|
||||
.Dq d/m/y ,
|
||||
.Dq m/d/y ,
|
||||
.Dq y/m/d .
|
||||
.El
|
||||
.Pp
|
||||
.Fn bsddialog_form
|
||||
@ -676,11 +619,16 @@ builds a dialog to display an array of
|
||||
.Fa items
|
||||
of
|
||||
.Fa nitems
|
||||
elements to get strings in input.
|
||||
elements to get input strings.
|
||||
.Fa formrows
|
||||
specifies the graphical height for the box around the items,
|
||||
is the graphical height for the items inside the dialog,
|
||||
.Dv 0
|
||||
for autosizing.
|
||||
If not
|
||||
.Dv NULL
|
||||
.Fa focusitem
|
||||
is the default item index on startup and the last focused item at exit, a
|
||||
negative value if no item is focused.
|
||||
An item is defined like:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
@ -703,7 +651,7 @@ struct bsddialog_formitem {
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa label
|
||||
is a string to describe the request, it is printed at the position
|
||||
is a string to describe the request at the position
|
||||
.Fa ylabel
|
||||
and
|
||||
.Fa xlabel .
|
||||
@ -717,22 +665,20 @@ is its graphical width, while
|
||||
is the maximum number of characters of the input string.
|
||||
.Fa init
|
||||
is the default field value.
|
||||
If the OK button is pressed
|
||||
If no error occurs
|
||||
.Fa value
|
||||
is the allocated memory with the current field string, its size depends on
|
||||
the current locale.
|
||||
is the allocated memory with the current field string at exit, its size depends
|
||||
on the current locale.
|
||||
.Fa flags
|
||||
is an OR value to set the
|
||||
is an OR value to set the field:
|
||||
.Dv BSDDIALOG_FIELDHIDDEN ,
|
||||
.Dv BSDDIALOG_FIELDREADONLY ,
|
||||
.Dv BSDDIALOG_FIELDNOCOLOR ,
|
||||
.Dv BSDDIALOG_FIELDCURSOREND ,
|
||||
.Dv BSDDIALOG_FIELDEXTEND
|
||||
and
|
||||
.Dv BSDDIALOG_FIELDEXTEND ,
|
||||
.Dv BSDDIALOG_FIELDSINGLEBYTE .
|
||||
flags for the field.
|
||||
.Fa bottomdesc
|
||||
is printed on the bottom side of the screen if the item is focused.
|
||||
is printed at bottom screen if the item is focused.
|
||||
.Pp
|
||||
.Fn bsddialog_form
|
||||
can be customized by:
|
||||
@ -751,38 +697,108 @@ the allocated
|
||||
is a
|
||||
.Em wchar_t*
|
||||
string.
|
||||
.It Fa conf.form.value_without_ok
|
||||
allocate memory and set
|
||||
.Fa value
|
||||
also if the OK button is not pressed.
|
||||
.El
|
||||
.Pp
|
||||
.Fn bsddialog_gauge
|
||||
builds a dialog with a bar to shows
|
||||
.Fa perc ,
|
||||
if the file descriptor
|
||||
builds a dialog with a bar to show
|
||||
.Fa perc .
|
||||
If the file descriptor
|
||||
.Fa fd
|
||||
is greater or equal to 0 the dialog waits to read
|
||||
.Fa separator
|
||||
.Fa sep
|
||||
from it, then the first string replaces
|
||||
.Fa perc
|
||||
and the following strings replace
|
||||
.Fa text
|
||||
until the next
|
||||
.Fa separator ,
|
||||
.Fa sep ,
|
||||
the loop ends reading
|
||||
.Dv EOF .
|
||||
.Fa end .
|
||||
.Pp
|
||||
.Fn bsddialog_infobox
|
||||
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:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
struct bsddialog_menuitem {
|
||||
const char *prefix;
|
||||
bool on;
|
||||
unsigned int depth;
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *bottomdesc;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa prefix ,
|
||||
.Fa name
|
||||
and
|
||||
.Fa desc
|
||||
are printed at the item row.
|
||||
.Fa bottomdesc
|
||||
is printed at bottom screen if the item is focused.
|
||||
.Fa depth
|
||||
is a margin between
|
||||
.Fa prefix
|
||||
and
|
||||
.Fa name .
|
||||
At exit
|
||||
.Fa on
|
||||
is set to
|
||||
.Dv true
|
||||
if the item is selected,
|
||||
.Dv false
|
||||
otherwise.
|
||||
.Fa items
|
||||
is an array of items of
|
||||
.Fa nitem
|
||||
elements.
|
||||
.Fa menurows
|
||||
is the graphical height of the list inside the dialog, if
|
||||
.Fa cols
|
||||
is
|
||||
.Dv BSDDIALOG_AUTOSIZE
|
||||
.Fa menurows
|
||||
specifies a maximum value.
|
||||
if not
|
||||
.Dv NULL
|
||||
.Fa focusitem
|
||||
is the default item index on startup and the last focused item at exit, a
|
||||
negative value if no item is focused.
|
||||
.Pp
|
||||
.Fn bsddialog_checklist ,
|
||||
.Fn bsddialog_menu ,
|
||||
.Fn bsddialog_mixedlist
|
||||
and
|
||||
.Fn bsddialog_radiolist
|
||||
can be customized by:
|
||||
.Bl -column -compact
|
||||
.It Fa conf.menu.align_left
|
||||
align items to left, default center.
|
||||
.It Fa conf.menu.no_desc
|
||||
hide items description.
|
||||
.It Fa conf.menu.no_name
|
||||
hide items name, mutually exclusive with
|
||||
.Fa conf.menu.no_desc .
|
||||
.It Fa conf.menu.shortcut_buttons
|
||||
enable shortcut keys on buttons, default on items.
|
||||
.El
|
||||
.Pp
|
||||
.Fn bsddialog_mixedgauge
|
||||
draws a main bar with the
|
||||
builds a dialog with a main bar with the
|
||||
.Fa mainperc
|
||||
percentage and
|
||||
.Fa nminibars
|
||||
each one with a
|
||||
.Fa minilabel
|
||||
and a
|
||||
.Fa miniperc .
|
||||
.Fa miniperc
|
||||
with a value between 0 and 100 or
|
||||
can be: a positive value to print a bar with a percentace, a negative constant
|
||||
.Dv BSDDIALOG_MG_SUCCEEDED ,
|
||||
.Dv BSDDIALOG_MG_FAILED ,
|
||||
.Dv BSDDIALOG_MG_PASSED ,
|
||||
@ -791,11 +807,69 @@ with a value between 0 and 100 or
|
||||
.Dv BSDDIALOG_MG_DONE ,
|
||||
.Dv BSDDIALOG_MG_SKIPPED ,
|
||||
.Dv BSDDIALOG_MG_INPROGRESS ,
|
||||
.Dv BSDDIALOG_MG_BLANK ,
|
||||
.Dv BSDDIALOG_MG_NA
|
||||
or
|
||||
.Dv BSDDIALOG_MG_BLANK
|
||||
to hide
|
||||
.Fa miniperc ,
|
||||
.Dv BSDDIALOG_MG_NA ,
|
||||
.Dv BSDDIALOG_MG_PENDING
|
||||
to print a descriptive string.
|
||||
to print a descriptive string, otherwise
|
||||
.Dq "UNKNOWN"
|
||||
is printed.
|
||||
.Pp
|
||||
.Fn bsddialog_mixedlist
|
||||
builds a dialog with collections of checklists, radiolists and separators.
|
||||
A collection is a set defined like:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
enum bsddialog_menutype {
|
||||
BSDDIALOG_CHECKLIST,
|
||||
BSDDIALOG_RADIOLIST,
|
||||
BSDDIALOG_SEPARATOR,
|
||||
};
|
||||
|
||||
struct bsddialog_menugroup {
|
||||
enum bsddialog_menutype type;
|
||||
unsigned int nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
unsigned int min_on; /* unused for now */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa groups
|
||||
is an array of sets of
|
||||
.Fa ngroups
|
||||
elements.
|
||||
.Fa menurows
|
||||
is the graphical height size for the list.
|
||||
If not
|
||||
.Dv NULL ,
|
||||
.Fa focuslist
|
||||
and
|
||||
.Fa focusitem
|
||||
specify the default item on startup and the last focused item at exit, could be
|
||||
a negative value if no item is focused.
|
||||
The dialog can be customized by
|
||||
.Fa conf.menu.* ,
|
||||
see
|
||||
.Fn bsddialog_menu .
|
||||
.Pp
|
||||
.Fn bsddialog_msgbox
|
||||
builds a dialog with OK button.
|
||||
.Pp
|
||||
.Fn bsddialog_pause
|
||||
builds a dialog waiting until the timeout in
|
||||
.Fa seconds
|
||||
expires or a button is pressed.
|
||||
At exit
|
||||
.Fa seconds
|
||||
is set like remaining time.
|
||||
.Pp
|
||||
.Fn bsddialog_radiolist
|
||||
builds dialogs to select at most an item from a list via the SPACE key, can be
|
||||
customized by
|
||||
.Fa conf.menu.* .
|
||||
See
|
||||
.Fn bsddialog_menu .
|
||||
.Pp
|
||||
.Fn bsddialog_rangebox
|
||||
to select a value between
|
||||
@ -809,12 +883,28 @@ and PAGEDOWN can change it.
|
||||
.Pp
|
||||
.Fn bsddialog_textbox
|
||||
opens and prints
|
||||
.Fa file
|
||||
in a dialog, the UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to
|
||||
navigate the file.
|
||||
OK button is renamed EXIT.
|
||||
.Fa file .
|
||||
UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
|
||||
navigate the file, TAB changes button.
|
||||
.Dq OK
|
||||
button is renamed
|
||||
.Dq EXIT .
|
||||
.Pp
|
||||
.Fn bsddialog_timebox
|
||||
builds a dialog to choose a time.
|
||||
.Fa hh ,
|
||||
.Fa mm ,
|
||||
and
|
||||
.Fa ss
|
||||
are default values on startup, selected time at exit.
|
||||
.Pp
|
||||
.Fn bsddialog_yesno
|
||||
provides a dialog for a
|
||||
.Dq Yes-No Question ,
|
||||
the labels on buttons are Yes and No.
|
||||
.Ss Theme
|
||||
The graphical properties are global to the library, they are represented by
|
||||
The graphical properties are global to the library.
|
||||
They are represented by
|
||||
.Fa struct bsddialog_theme
|
||||
and can be customized at runtime via the
|
||||
.In bsddialog_theme.h
|
||||
@ -840,17 +930,19 @@ struct bsddialog_theme {
|
||||
int arrowcolor;
|
||||
} dialog;
|
||||
struct {
|
||||
int f_prefixcolor;
|
||||
int prefixcolor;
|
||||
int f_selectorcolor;
|
||||
int selectorcolor;
|
||||
int f_namecolor;
|
||||
int namecolor;
|
||||
int f_desccolor;
|
||||
int desccolor;
|
||||
int namesepcolor;
|
||||
int descsepcolor;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
int bottomdesccolor;
|
||||
int sepnamecolor;
|
||||
int sepdesccolor;
|
||||
} menu;
|
||||
struct {
|
||||
int f_fieldcolor;
|
||||
@ -867,32 +959,27 @@ struct bsddialog_theme {
|
||||
unsigned int maxmargin;
|
||||
char leftdelim;
|
||||
char rightdelim;
|
||||
int delimcolor;
|
||||
int f_delimcolor;
|
||||
int color;
|
||||
int delimcolor;
|
||||
int f_color;
|
||||
int shortcutcolor;
|
||||
int color;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
} button;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
A member with the
|
||||
.Dq f_
|
||||
prefix refers to an element with focus.
|
||||
refers to focus when an element can be in selected or not selected state.
|
||||
.Pp
|
||||
.Fn bsddialog_get_theme
|
||||
sets
|
||||
.Fa theme
|
||||
like the current theme.
|
||||
.Pp
|
||||
A color can be set by the value returned by
|
||||
.Fn bsddialog_color ,
|
||||
Possible values for
|
||||
.Fa background
|
||||
and
|
||||
.Fa foreground
|
||||
are:
|
||||
.Fn bsddialog_color
|
||||
generates and returns a color to set a
|
||||
.Fa struct bsddialog_theme
|
||||
color member.
|
||||
An
|
||||
.Fa enum bsddialog_color
|
||||
can be:
|
||||
.Dv BSDDIALOG_BLACK ,
|
||||
.Dv BSDDIALOG_RED ,
|
||||
.Dv BSDDIALOG_GREEN ,
|
||||
@ -900,31 +987,30 @@ are:
|
||||
.Dv BSDDIALOG_BLUE ,
|
||||
.Dv BSDDIALOG_MAGENTA ,
|
||||
.Dv BSDDIALOG_CYAN ,
|
||||
and
|
||||
.Dv BSDDIALOG_WHITE ,
|
||||
.Dv BSDDIALOG_WHITE .
|
||||
.Fa flags
|
||||
specifies OR-flags, possible values:
|
||||
is an OR value:
|
||||
.Dv BSDDIALOG_BLINK ,
|
||||
.Dv BSDDIALOG_BOLD ,
|
||||
.Dv BSDDIALOG_REVERSE
|
||||
and
|
||||
.Dv BSDDIALOG_HALFBRIGHT ,
|
||||
.Dv BSDDIALOG_HIGHLIGHT ,
|
||||
.Dv BSDDIALOG_REVERSE ,
|
||||
.Dv BSDDIALOG_UNDERLINE .
|
||||
.Fn bsddialog_color_attrs
|
||||
gets the properties of a color.
|
||||
.Pp
|
||||
.Fn bsddialog_set_theme
|
||||
.Fn bsddialog_color_attrs
|
||||
sets, if not NULL,
|
||||
.Fa foreground ,
|
||||
.Fa background ,
|
||||
.Fa flags ,
|
||||
like the properties of
|
||||
.Fa color ,
|
||||
see
|
||||
.Fn bsddialog_color .
|
||||
.Pp
|
||||
.Fn bsddialog_get_theme
|
||||
sets
|
||||
.Fa theme
|
||||
like current theme, the changes takes effect only for dialogs built after the
|
||||
call.
|
||||
.Pp
|
||||
The library provides predefined themes:
|
||||
.Dv BSDDIALOG_THEME_BLACKWHITE ,
|
||||
.Dv BSDDIALOG_THEME_BSDDIALOG ,
|
||||
.Dv BSDDIALOG_THEME_FLAT
|
||||
and
|
||||
.Dv BSDDIALOG_THEME_DIALOG ,
|
||||
they can be set via
|
||||
.Fn bsddialog_set_default_theme .
|
||||
like the current runtime theme.
|
||||
.Pp
|
||||
.Fn bsddialog_hascolors
|
||||
returns
|
||||
@ -932,6 +1018,20 @@ returns
|
||||
if the terminal provides colors,
|
||||
.Dv false
|
||||
otherwise.
|
||||
.Pp
|
||||
.Fn bsddialog_set_theme
|
||||
sets
|
||||
.Fa theme
|
||||
like current runtime theme.
|
||||
Changes take effect only for dialogs built after
|
||||
the call.
|
||||
.Pp
|
||||
.Fn bsddialog_set_default_theme
|
||||
sets a library default theme like current theme, possible values:
|
||||
.Dv BSDDIALOG_THEME_BLACKWHITE ,
|
||||
.Dv BSDDIALOG_THEME_FLAT ,
|
||||
.Dv BSDDIALOG_THEME_3D .
|
||||
Changes take effect only for dialogs built after the call.
|
||||
.Sh RETURN VALUES
|
||||
The functions return the value
|
||||
.Dv BSDDIALOG_ERROR
|
||||
@ -942,9 +1042,12 @@ returned:
|
||||
.Dv BSDDIALOG_CANCEL ,
|
||||
.Dv BSDDIALOG_HELP ,
|
||||
.Dv BSDDIALOG_EXTRA ,
|
||||
.Dv BSDDIALOG_GENERIC1
|
||||
or
|
||||
.Dv BSDDIALOG_GENERIC2 .
|
||||
.Dv BSDDIALOG_LEFT1 ,
|
||||
.Dv BSDDIALOG_LEFT2 ,
|
||||
.Dv BSDDIALOG_LEFT3 ,
|
||||
.Dv BSDDIALOG_RIGHT1 ,
|
||||
.Dv BSDDIALOG_RIGHT2 ,
|
||||
.Dv BSDDIALOG_RIGHT3 .
|
||||
.Dv BSDDIALOG_YES
|
||||
and
|
||||
.Dv BSDDIALOG_NO
|
||||
@ -990,6 +1093,7 @@ case BSDDIALOG_NO
|
||||
break;
|
||||
case BSDDIALOG_ERROR:
|
||||
printf("Error: %s\\n", bsddialog_geterror());
|
||||
break;
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,9 +30,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LIBBSDDIALOG_VERSION "0.4"
|
||||
#define LIBBSDDIALOG_VERSION "1.0"
|
||||
|
||||
/* Exit status */
|
||||
/* Return values */
|
||||
#define BSDDIALOG_ERROR -1
|
||||
#define BSDDIALOG_OK 0
|
||||
#define BSDDIALOG_YES BSDDIALOG_OK
|
||||
@ -42,8 +42,12 @@
|
||||
#define BSDDIALOG_EXTRA 3
|
||||
#define BSDDIALOG_TIMEOUT 4
|
||||
#define BSDDIALOG_ESC 5
|
||||
#define BSDDIALOG_GENERIC1 6
|
||||
#define BSDDIALOG_GENERIC2 7
|
||||
#define BSDDIALOG_LEFT1 6
|
||||
#define BSDDIALOG_LEFT2 7
|
||||
#define BSDDIALOG_LEFT3 8
|
||||
#define BSDDIALOG_RIGHT1 9
|
||||
#define BSDDIALOG_RIGHT2 10
|
||||
#define BSDDIALOG_RIGHT3 11
|
||||
|
||||
/* Size and position */
|
||||
#define BSDDIALOG_FULLSCREEN -1
|
||||
@ -94,24 +98,28 @@ struct bsddialog_conf {
|
||||
} key;
|
||||
struct {
|
||||
unsigned int cols_per_row;
|
||||
bool highlight;
|
||||
bool escape;
|
||||
unsigned int tablen;
|
||||
} text;
|
||||
struct {
|
||||
bool align_left;
|
||||
bool no_desc;
|
||||
bool no_name;
|
||||
bool on_without_ok;
|
||||
bool shortcut_buttons;
|
||||
} menu;
|
||||
struct {
|
||||
char securech;
|
||||
char *securembch;
|
||||
bool value_wchar;
|
||||
bool value_without_ok;
|
||||
} form;
|
||||
struct {
|
||||
const char *format;
|
||||
} date;
|
||||
struct {
|
||||
bool always_active;
|
||||
const char *left1_label;
|
||||
const char *left2_label;
|
||||
const char *left3_label;
|
||||
bool without_ok;
|
||||
const char *ok_label;
|
||||
bool with_extra;
|
||||
@ -121,8 +129,9 @@ struct bsddialog_conf {
|
||||
bool default_cancel;
|
||||
bool with_help;
|
||||
const char *help_label;
|
||||
const char *generic1_label;
|
||||
const char *generic2_label;
|
||||
const char *right1_label;
|
||||
const char *right2_label;
|
||||
const char *right3_label;
|
||||
const char *default_label;
|
||||
} button;
|
||||
};
|
||||
@ -146,6 +155,7 @@ struct bsddialog_menugroup {
|
||||
enum bsddialog_menutype type;
|
||||
unsigned int nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
unsigned int min_on; /* unused for now */
|
||||
};
|
||||
|
||||
struct bsddialog_formitem {
|
||||
@ -166,16 +176,18 @@ struct bsddialog_formitem {
|
||||
|
||||
int bsddialog_init(void);
|
||||
int bsddialog_init_notheme(void);
|
||||
bool bsddialog_inmode(void);
|
||||
int bsddialog_end(void);
|
||||
int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle);
|
||||
int bsddialog_initconf(struct bsddialog_conf *conf);
|
||||
int bsddialog_clearterminal(void);
|
||||
void bsddialog_clear(unsigned int y);
|
||||
void bsddialog_refresh(void);
|
||||
const char *bsddialog_geterror(void);
|
||||
|
||||
/* Dialogs */
|
||||
int
|
||||
bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd);
|
||||
int cols, unsigned int *year, unsigned int *month, unsigned int *day);
|
||||
|
||||
int
|
||||
bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
@ -184,16 +196,16 @@ bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
int
|
||||
bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd);
|
||||
int cols, unsigned int *year, unsigned int *month, unsigned int *day);
|
||||
|
||||
int
|
||||
bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int formheight, unsigned int nitems,
|
||||
struct bsddialog_formitem *items);
|
||||
struct bsddialog_formitem *items, int *focusitem);
|
||||
|
||||
int
|
||||
bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int perc, int fd, const char *sep);
|
||||
int cols, unsigned int perc, int fd, const char *sep, const char *end);
|
||||
|
||||
int
|
||||
bsddialog_infobox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
@ -220,7 +232,7 @@ bsddialog_msgbox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
int
|
||||
bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int seconds);
|
||||
int cols, unsigned int *seconds);
|
||||
|
||||
int
|
||||
bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -36,14 +36,14 @@
|
||||
|
||||
extern bool bsddialog_interruptprogview;
|
||||
extern bool bsddialog_abortprogview;
|
||||
extern int bsddialog_total_progview;
|
||||
extern long long int bsddialog_total_progview;
|
||||
|
||||
struct bsddialog_fileminibar {
|
||||
const char *path;
|
||||
const char *label;
|
||||
int status; /* next if BSDDIALOG_MG_DONE or BSDDIALOG_MG_FAILED */
|
||||
long long size;
|
||||
long long read;
|
||||
long long int size;
|
||||
long long int read;
|
||||
};
|
||||
|
||||
struct bsddialog_progviewconf {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -29,9 +29,12 @@
|
||||
#define _LIBBSDDIALOG_THEME_H_
|
||||
|
||||
/* color flags */
|
||||
#define BSDDIALOG_BOLD 1U
|
||||
#define BSDDIALOG_REVERSE 2U
|
||||
#define BSDDIALOG_UNDERLINE 4U
|
||||
#define BSDDIALOG_BLINK 1U
|
||||
#define BSDDIALOG_BOLD 2U
|
||||
#define BSDDIALOG_HALFBRIGHT 4U
|
||||
#define BSDDIALOG_HIGHLIGHT 8U
|
||||
#define BSDDIALOG_REVERSE 16U
|
||||
#define BSDDIALOG_UNDERLINE 32U
|
||||
|
||||
struct bsddialog_theme {
|
||||
struct {
|
||||
@ -52,17 +55,19 @@ struct bsddialog_theme {
|
||||
int arrowcolor;
|
||||
} dialog;
|
||||
struct {
|
||||
int f_prefixcolor;
|
||||
int prefixcolor;
|
||||
int f_selectorcolor;
|
||||
int selectorcolor;
|
||||
int f_namecolor;
|
||||
int namecolor;
|
||||
int f_desccolor;
|
||||
int desccolor;
|
||||
int namesepcolor;
|
||||
int descsepcolor;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
int bottomdesccolor;
|
||||
int sepnamecolor;
|
||||
int sepdesccolor;
|
||||
} menu;
|
||||
struct {
|
||||
int f_fieldcolor;
|
||||
@ -79,20 +84,19 @@ struct bsddialog_theme {
|
||||
unsigned int maxmargin;
|
||||
char leftdelim;
|
||||
char rightdelim;
|
||||
int delimcolor;
|
||||
int f_delimcolor;
|
||||
int color;
|
||||
int delimcolor;
|
||||
int f_color;
|
||||
int shortcutcolor;
|
||||
int color;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
} button;
|
||||
};
|
||||
|
||||
enum bsddialog_default_theme {
|
||||
BSDDIALOG_THEME_3D,
|
||||
BSDDIALOG_THEME_BLACKWHITE,
|
||||
BSDDIALOG_THEME_BSDDIALOG,
|
||||
BSDDIALOG_THEME_FLAT,
|
||||
BSDDIALOG_THEME_DIALOG
|
||||
BSDDIALOG_THEME_FLAT
|
||||
};
|
||||
|
||||
enum bsddialog_color {
|
||||
|
@ -1,520 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
715
contrib/bsddialog/lib/datebox.c
Normal file
715
contrib/bsddialog/lib/datebox.c
Normal file
@ -0,0 +1,715 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2022-2023 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 <curses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
/* Calendar */
|
||||
#define MIN_YEAR_CAL 0
|
||||
#define MAX_YEAR_CAL 999999999
|
||||
#define MINHCAL 13
|
||||
#define MINWCAL 36 /* 34 calendar, 1 + 1 margins */
|
||||
/* Datebox */
|
||||
#define MIN_YEAR_DATE 0
|
||||
#define MAX_YEAR_DATE 9999
|
||||
#define MINWDATE 23 /* 3 windows and their borders */
|
||||
|
||||
#define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
|
||||
|
||||
static int minyear;
|
||||
static int maxyear;
|
||||
|
||||
static const char *m[12] = {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
};
|
||||
|
||||
enum operation {
|
||||
UP_DAY,
|
||||
DOWN_DAY,
|
||||
LEFT_DAY,
|
||||
RIGHT_DAY,
|
||||
UP_MONTH,
|
||||
DOWN_MONTH,
|
||||
UP_YEAR,
|
||||
DOWN_YEAR
|
||||
};
|
||||
|
||||
/* private datebox item */
|
||||
struct dateitem {
|
||||
enum operation up;
|
||||
enum operation down;
|
||||
WINDOW *win;
|
||||
int width;
|
||||
const char *fmt;
|
||||
int *value;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
init_date(unsigned int *year, unsigned int *month, unsigned int *day, int *yy,
|
||||
int *mm, int *dd)
|
||||
{
|
||||
*yy = MIN(*year, (unsigned int)maxyear);
|
||||
if (*yy < minyear)
|
||||
*yy = minyear;
|
||||
*mm = MIN(*month, 12);
|
||||
if (*mm == 0)
|
||||
*mm = 1;
|
||||
*dd = (*day == 0) ? 1 : *day;
|
||||
if(*dd > month_days(*yy, *mm))
|
||||
*dd = month_days(*yy, *mm);
|
||||
}
|
||||
|
||||
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 void
|
||||
drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev,
|
||||
const char *fmt, int value, bool focus)
|
||||
{
|
||||
int h, l, w;
|
||||
|
||||
getmaxyx(win, h, w);
|
||||
draw_borders(conf, win, 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);
|
||||
wattroff(win, t.dialog.arrowcolor);
|
||||
}
|
||||
|
||||
if (focus)
|
||||
wattron(win, t.menu.f_namecolor);
|
||||
if (strchr(fmt, 's') != NULL)
|
||||
mvwprintw(win, 1, 1, fmt, m[value - 1]);
|
||||
else
|
||||
mvwprintw(win, 1, 1, fmt, value);
|
||||
if (focus)
|
||||
wattroff(win, t.menu.f_namecolor);
|
||||
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
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, 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++;
|
||||
}
|
||||
}
|
||||
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
static int
|
||||
calendar_redraw(struct dialog *d, WINDOW *yy_win, WINDOW *mm_win,
|
||||
WINDOW *dd_win)
|
||||
{
|
||||
int ycal, xcal;
|
||||
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(d, MINHCAL, MINWCAL, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
TEXTPAD(d, MINHCAL + HBUTTONS);
|
||||
|
||||
ycal = d->y + d->h - 15;
|
||||
xcal = d->x + d->w/2 - 17;
|
||||
mvwaddstr(d->widget, d->h - 16, d->w/2 - 17, "Month");
|
||||
update_box(d->conf, mm_win, ycal, xcal, 3, 17, RAISED);
|
||||
mvwaddstr(d->widget, d->h - 16, d->w/2, "Year");
|
||||
update_box(d->conf, yy_win, ycal, xcal + 17, 3, 17, RAISED);
|
||||
update_box(d->conf, dd_win, ycal + 3, xcal, 9, 34, RAISED);
|
||||
wnoutrefresh(d->widget);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int *year, unsigned int *month, unsigned int *day)
|
||||
{
|
||||
bool loop, focusbuttons;
|
||||
int retval, sel, yy, mm, dd;
|
||||
wint_t input;
|
||||
WINDOW *yy_win, *mm_win, *dd_win;
|
||||
struct dialog d;
|
||||
|
||||
CHECK_PTR(year);
|
||||
CHECK_PTR(month);
|
||||
CHECK_PTR(day);
|
||||
minyear = MIN_YEAR_CAL;
|
||||
maxyear = MAX_YEAR_CAL;
|
||||
init_date(year, month, day, &yy, &mm, &dd);
|
||||
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
|
||||
if ((yy_win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW for yy");
|
||||
wbkgd(yy_win, t.dialog.color);
|
||||
if ((mm_win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW for mm");
|
||||
wbkgd(mm_win, t.dialog.color);
|
||||
if ((dd_win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_ERROR("Cannot build WINDOW for dd");
|
||||
wbkgd(dd_win, t.dialog.color);
|
||||
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
drawsquare(conf, mm_win, RAISED, "%15s", mm, sel == 0);
|
||||
drawsquare(conf, yy_win, RAISED, "%15d", yy, sel == 1);
|
||||
print_calendar(conf, dd_win, yy, mm, dd, sel == 2);
|
||||
doupdate();
|
||||
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
if (focusbuttons || conf->button.always_active) {
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case '\t': /* TAB */
|
||||
if (focusbuttons) {
|
||||
d.bs.curr++;
|
||||
if (d.bs.curr >= (int)d.bs.nbuttons) {
|
||||
focusbuttons = false;
|
||||
sel = 0;
|
||||
d.bs.curr = conf->button.always_active ?
|
||||
0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
if (sel > 2) {
|
||||
focusbuttons = true;
|
||||
sel = -1;
|
||||
d.bs.curr = 0;
|
||||
}
|
||||
}
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (focusbuttons) {
|
||||
d.bs.curr++;
|
||||
if (d.bs.curr >= (int)d.bs.nbuttons) {
|
||||
focusbuttons = false;
|
||||
sel = 0;
|
||||
d.bs.curr = conf->button.always_active ?
|
||||
0 : -1;
|
||||
}
|
||||
} else if (sel == 2) {
|
||||
datectl(RIGHT_DAY, &yy, &mm, &dd);
|
||||
} else { /* Month or Year*/
|
||||
sel++;
|
||||
}
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (focusbuttons) {
|
||||
d.bs.curr--;
|
||||
if (d.bs.curr < 0) {
|
||||
focusbuttons = false;
|
||||
sel = 2;
|
||||
d.bs.curr = conf->button.always_active ?
|
||||
0 : -1;
|
||||
}
|
||||
} else if (sel == 2) {
|
||||
datectl(LEFT_DAY, &yy, &mm, &dd);
|
||||
} else if (sel == 1) {
|
||||
sel = 0;
|
||||
} else { /* sel = 0, Month */
|
||||
focusbuttons = true;
|
||||
sel = -1;
|
||||
d.bs.curr = 0;
|
||||
}
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons) {
|
||||
sel = 2;
|
||||
focusbuttons = false;
|
||||
d.bs.curr = conf->button.always_active ? 0 : -1;
|
||||
DRAW_BUTTONS(d);
|
||||
} else if (sel == 0) {
|
||||
datectl(UP_MONTH, &yy, &mm, &dd);
|
||||
} else if (sel == 1) {
|
||||
datectl(UP_YEAR, &yy, &mm, &dd);
|
||||
} else { /* sel = 2 */
|
||||
datectl(UP_DAY, &yy, &mm, &dd);
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
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(DOWN_DAY, &yy, &mm, &dd);
|
||||
}
|
||||
break;
|
||||
case KEY_HOME:
|
||||
datectl(UP_MONTH, &yy, &mm, &dd);
|
||||
break;
|
||||
case KEY_END:
|
||||
datectl(DOWN_MONTH, &yy, &mm, &dd);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
datectl(UP_YEAR, &yy, &mm, &dd);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
datectl(DOWN_YEAR, &yy, &mm, &dd);
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help_dialog(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
case KEY_RESIZE:
|
||||
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*year = yy;
|
||||
*month = mm;
|
||||
*day = dd;
|
||||
|
||||
delwin(yy_win);
|
||||
delwin(mm_win);
|
||||
delwin(dd_win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int datebox_redraw(struct dialog *d, struct dateitem *di)
|
||||
{
|
||||
int y, x;
|
||||
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(d, 3 /*windows*/, MINWDATE, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
TEXTPAD(d, 3 /*windows*/ + HBUTTONS);
|
||||
|
||||
y = d->y + d->h - 6;
|
||||
x = (d->x + d->w / 2) - 11;
|
||||
update_box(d->conf, di[0].win, y, x, 3, di[0].width, LOWERED);
|
||||
mvwaddch(d->widget, d->h - 5, x - d->x + di[0].width, '/');
|
||||
x += di[0].width + 1;
|
||||
update_box(d->conf, di[1].win, y, x , 3, di[1].width, LOWERED);
|
||||
mvwaddch(d->widget, d->h - 5, x - d->x + di[1].width, '/');
|
||||
x += di[1].width + 1;
|
||||
update_box(d->conf, di[2].win, y, x, 3, di[2].width, LOWERED);
|
||||
wnoutrefresh(d->widget);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
build_dateitem(const char *format, int *yy, int *mm, int *dd,
|
||||
struct dateitem *dt)
|
||||
{
|
||||
int i;
|
||||
wchar_t *wformat;
|
||||
struct dateitem init[3] = {
|
||||
{UP_YEAR, DOWN_YEAR, NULL, 6, "%4d", yy},
|
||||
{UP_MONTH, DOWN_MONTH, NULL, 11, "%9s", mm},
|
||||
{LEFT_DAY, RIGHT_DAY, NULL, 4, "%02d", dd},
|
||||
};
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((init[i].win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_FMTERROR("Cannot build WINDOW dateitem[%d]", i);
|
||||
wbkgd(init[i].win, t.dialog.color);
|
||||
}
|
||||
|
||||
if ((wformat = alloc_mbstows(CHECK_STR(format))) == NULL)
|
||||
RETURN_ERROR("Cannot allocate conf.date.format in wchar_t*");
|
||||
if (format == NULL || wcscmp(wformat, L"d/m/y") == 0) {
|
||||
dt[0] = init[2];
|
||||
dt[1] = init[1];
|
||||
dt[2] = init[0];
|
||||
} else if (wcscmp(wformat, L"m/d/y") == 0) {
|
||||
dt[0] = init[1];
|
||||
dt[1] = init[2];
|
||||
dt[2] = init[0];
|
||||
} else if (wcscmp(wformat, L"y/m/d") == 0) {
|
||||
dt[0] = init[0];
|
||||
dt[1] = init[1];
|
||||
dt[2] = init[2];
|
||||
} else
|
||||
RETURN_FMTERROR("Invalid conf.date.format=\"%s\"", format);
|
||||
free(wformat);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int *year, unsigned int *month, unsigned int *day)
|
||||
{
|
||||
bool loop, focusbuttons;
|
||||
int retval, i, sel, yy, mm, dd;
|
||||
wint_t input;
|
||||
struct dateitem di[3];
|
||||
struct dialog d;
|
||||
|
||||
CHECK_PTR(year);
|
||||
CHECK_PTR(month);
|
||||
CHECK_PTR(day);
|
||||
minyear = MIN_YEAR_DATE;
|
||||
maxyear = MAX_YEAR_DATE;
|
||||
init_date(year, month, day, &yy, &mm, &dd);
|
||||
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
|
||||
if (build_dateitem(conf->date.format, &yy, &mm, &dd, di) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datebox_redraw(&d, di) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
for (i = 0; i < 3; i++)
|
||||
drawsquare(conf, di[i].win, LOWERED, di[i].fmt,
|
||||
*di[i].value, sel == i);
|
||||
doupdate();
|
||||
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
if (focusbuttons || conf->button.always_active) {
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case '\t': /* TAB */
|
||||
if (focusbuttons) {
|
||||
d.bs.curr++;
|
||||
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
|
||||
true : false;
|
||||
if (focusbuttons == false) {
|
||||
sel = 0;
|
||||
d.bs.curr = conf->button.always_active ?
|
||||
0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
focusbuttons = sel > 2 ? true : false;
|
||||
if (focusbuttons) {
|
||||
d.bs.curr = 0;
|
||||
}
|
||||
}
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (focusbuttons) {
|
||||
d.bs.curr--;
|
||||
focusbuttons = d.bs.curr < 0 ? false : true;
|
||||
if (focusbuttons == false) {
|
||||
sel = 2;
|
||||
d.bs.curr = conf->button.always_active ?
|
||||
0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel--;
|
||||
focusbuttons = sel < 0 ? true : false;
|
||||
if (focusbuttons)
|
||||
d.bs.curr = (int)d.bs.nbuttons - 1;
|
||||
}
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons) {
|
||||
sel = 0;
|
||||
focusbuttons = false;
|
||||
d.bs.curr = conf->button.always_active ? 0 : -1;
|
||||
DRAW_BUTTONS(d);
|
||||
} else {
|
||||
datectl(di[sel].up, &yy, &mm, &dd);
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (focusbuttons)
|
||||
break;
|
||||
datectl(di[sel].down, &yy, &mm, &dd);
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help_dialog(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datebox_redraw(&d, di) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
case KEY_RESIZE:
|
||||
if (datebox_redraw(&d, di) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*year = yy;
|
||||
*month = mm;
|
||||
*day = dd;
|
||||
|
||||
for (i = 0; i < 3 ; i++)
|
||||
delwin(di[i].win);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,96 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-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 "bsddialog.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
static int
|
||||
infobox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, const char *text)
|
||||
{
|
||||
int htext, wtext;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, NULL, 0, 1, &htext,
|
||||
&wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, wtext, TEXTHMARGINS + 1, NULL);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 0, false);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int infobox_checksize(int rows, int cols)
|
||||
{
|
||||
if (cols < HBORDERS)
|
||||
RETURN_ERROR("Few cols, infobox needs at least width 2");
|
||||
|
||||
if (rows < VBORDERS)
|
||||
RETURN_ERROR("Infobox needs at least height 2");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* API */
|
||||
int
|
||||
bsddialog_infobox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols)
|
||||
{
|
||||
int y, x, h, w;
|
||||
WINDOW *shadow, *widget, *textpad;
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (infobox_autosize(conf, rows, cols, &h, &w, text) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (infobox_checksize(h, w) != 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,
|
||||
NULL, false) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
pnoutrefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-2,
|
||||
x+w-TEXTHMARGIN);
|
||||
|
||||
doupdate();
|
||||
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -28,117 +28,136 @@
|
||||
#ifndef _LIBBSDDIALOG_UTIL_H_
|
||||
#define _LIBBSDDIALOG_UTIL_H_
|
||||
|
||||
#define HBORDERS 2
|
||||
#define VBORDERS 2
|
||||
#define BORDER 1
|
||||
#define BORDERS (BORDER + BORDER)
|
||||
#define TEXTHMARGIN 1
|
||||
#define TEXTHMARGINS (TEXTHMARGIN + TEXTHMARGIN)
|
||||
#define HBUTTONS 2
|
||||
#define OK_LABEL "OK"
|
||||
#define CANCEL_LABEL "Cancel"
|
||||
|
||||
/* theme utils */
|
||||
/* theme util */
|
||||
extern struct bsddialog_theme t;
|
||||
extern bool hastermcolors;
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
/* debug */
|
||||
#define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \
|
||||
mvprintw(y, x, fmt, __VA_ARGS__); \
|
||||
refresh(); \
|
||||
#define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \
|
||||
mvprintw(y, x, fmt, __VA_ARGS__); \
|
||||
refresh(); \
|
||||
} while (0)
|
||||
/* error and diagnostic */
|
||||
#define RETURN_ERROR(str) do { \
|
||||
set_error_string(str); \
|
||||
return (BSDDIALOG_ERROR); \
|
||||
} while (0)
|
||||
#define RETURN_FMTERROR(fmt, ...) do { \
|
||||
set_fmt_error_string(fmt, __VA_ARGS__); \
|
||||
return (BSDDIALOG_ERROR); \
|
||||
} while (0)
|
||||
/* check ptr */
|
||||
#define CHECK_PTR(p) do { \
|
||||
if (p == NULL) \
|
||||
RETURN_ERROR("*" #p " is NULL"); \
|
||||
} while (0)
|
||||
#define CHECK_ARRAY(nitem, a) do { \
|
||||
if(nitem > 0 && a == NULL) \
|
||||
RETURN_FMTERROR(#nitem " is %d but *" #a " is NULL", nitem); \
|
||||
} while (0)
|
||||
/* widget utils */
|
||||
#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 DRAW_BUTTONS(d) do { \
|
||||
draw_buttons(&d); \
|
||||
wnoutrefresh(d.widget); \
|
||||
} while (0)
|
||||
|
||||
/* date */
|
||||
#define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
|
||||
/* internal types */
|
||||
enum elevation { RAISED, LOWERED };
|
||||
|
||||
/* unicode */
|
||||
struct buttons {
|
||||
unsigned int nbuttons;
|
||||
#define MAXBUTTONS 10 /* 3left + ok + extra + cancel + help + 3 right */
|
||||
const char *label[MAXBUTTONS];
|
||||
bool shortcut;
|
||||
wchar_t first[MAXBUTTONS];
|
||||
int value[MAXBUTTONS];
|
||||
int curr;
|
||||
#define BUTTONVALUE(bs) bs.value[bs.curr]
|
||||
unsigned int sizebutton; /* including left and right delimiters */
|
||||
};
|
||||
|
||||
struct dialog {
|
||||
bool built; /* true after the first draw_dialog() */
|
||||
struct bsddialog_conf *conf; /* Checked API conf */
|
||||
WINDOW *widget; /* Size and position refer to widget */
|
||||
int y, x; /* Current position, API conf.[y|x]: -1, >=0 */
|
||||
int rows, cols; /* API rows and cols: -1, 0, >0 */
|
||||
int h, w; /* Current height and width */
|
||||
const char *text; /* Checked API text, at least "" */
|
||||
WINDOW *textpad; /* Fake for textbox */
|
||||
struct buttons bs; /* bs.nbuttons = 0 for no buttons */
|
||||
WINDOW *shadow;
|
||||
};
|
||||
|
||||
/* error and diagnostic */
|
||||
const char *get_error_string(void);
|
||||
void set_error_string(const char *string);
|
||||
void set_fmt_error_string(const char *fmt, ...);
|
||||
|
||||
/* multicolumn character string */
|
||||
unsigned int strcols(const char *mbstring);
|
||||
int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col);
|
||||
void mvwaddwch(WINDOW *w, int y, int x, wchar_t wch);
|
||||
wchar_t* alloc_mbstows(const char *mbstring);
|
||||
|
||||
/* error buffer */
|
||||
const char *get_error_string(void);
|
||||
void set_error_string(const char *string);
|
||||
|
||||
#define RETURN_ERROR(str) do { \
|
||||
set_error_string(str); \
|
||||
return (BSDDIALOG_ERROR); \
|
||||
} while (0)
|
||||
|
||||
/* buttons */
|
||||
struct buttons {
|
||||
unsigned int nbuttons;
|
||||
#define MAXBUTTONS 6 /* ok + extra + cancel + help + 2 generics */
|
||||
const char *label[MAXBUTTONS];
|
||||
wchar_t first[MAXBUTTONS];
|
||||
int value[MAXBUTTONS];
|
||||
int curr;
|
||||
unsigned int sizebutton; /* including left and right delimiters */
|
||||
};
|
||||
|
||||
#define BUTTON_OK_LABEL "OK"
|
||||
#define BUTTON_CANCEL_LABEL "Cancel"
|
||||
void
|
||||
get_buttons(struct bsddialog_conf *conf, struct buttons *bs,
|
||||
const char *yesoklabel, const char *nocancellabel);
|
||||
|
||||
void
|
||||
draw_buttons(WINDOW *window, struct buttons bs, bool shortcut);
|
||||
|
||||
int buttons_min_width(struct buttons bs);
|
||||
set_buttons(struct dialog *d, bool shortcut, const char *oklabel,
|
||||
const char *canclabel);
|
||||
void draw_buttons(struct dialog *d);
|
||||
bool shortcut_buttons(wint_t key, struct buttons *bs);
|
||||
|
||||
/* help window with F1 key */
|
||||
int f1help(struct bsddialog_conf *conf);
|
||||
/* widget utils */
|
||||
int hide_dialog(struct dialog *d);
|
||||
int f1help_dialog(struct bsddialog_conf *conf);
|
||||
|
||||
/* cleaner */
|
||||
int hide_widget(int y, int x, int h, int w, bool withshadow);
|
||||
void
|
||||
draw_borders(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev);
|
||||
|
||||
/* (auto) size and (auto) position */
|
||||
#define SCREENLINES (getmaxy(stdscr))
|
||||
#define SCREENCOLS (getmaxx(stdscr))
|
||||
void
|
||||
update_box(struct bsddialog_conf *conf, WINDOW *win, int y, int x, int h, int w,
|
||||
enum elevation elev);
|
||||
|
||||
int
|
||||
text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
|
||||
struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext);
|
||||
|
||||
int widget_max_height(struct bsddialog_conf *conf);
|
||||
int widget_max_width(struct bsddialog_conf *conf);
|
||||
|
||||
int
|
||||
widget_min_height(struct bsddialog_conf *conf, int htext, int minwidget,
|
||||
bool withbuttons);
|
||||
|
||||
int
|
||||
widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
|
||||
struct buttons *bs);
|
||||
void
|
||||
rtextpad(struct dialog *d, int ytext, int xtext, int upnotext, int downnotext);
|
||||
|
||||
/* (auto) sizing and (auto) position */
|
||||
int
|
||||
set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w);
|
||||
|
||||
int
|
||||
set_widget_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, const char *text, int *rowstext, struct buttons *bs, int hnotext,
|
||||
int minw);
|
||||
|
||||
int widget_checksize(int h, int w, struct buttons *bs, int hnotext, int minw);
|
||||
|
||||
int
|
||||
set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w);
|
||||
|
||||
/* widget builders */
|
||||
enum elevation { RAISED, LOWERED };
|
||||
int dialog_size_position(struct dialog *d, int hnotext, int minw, int *htext);
|
||||
|
||||
void
|
||||
draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols,
|
||||
enum elevation elev);
|
||||
|
||||
WINDOW *
|
||||
new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols,
|
||||
enum elevation elev);
|
||||
/* dialog */
|
||||
void end_dialog(struct dialog *d);
|
||||
int draw_dialog(struct dialog *d);
|
||||
|
||||
int
|
||||
new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y,
|
||||
int x, int h, int w, WINDOW **textpad, const char *text, struct buttons *bs,
|
||||
bool shortcutbuttons);
|
||||
|
||||
int
|
||||
update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
int y, int x, int h, int w, WINDOW *textpad, const char *text,
|
||||
struct buttons *bs, bool shortcutbuttons);
|
||||
|
||||
void
|
||||
end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
WINDOW *textpad);
|
||||
prepare_dialog(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, struct dialog *d);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -26,15 +26,15 @@
|
||||
*/
|
||||
|
||||
#include <curses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
#define COLSPERROW 10 /* Default conf.text.columns_per_row */
|
||||
#define DEFAULT_COLS_PER_ROW 10 /* Default conf.text.columns_per_row */
|
||||
|
||||
static bool in_bsddialog_mode = false;
|
||||
|
||||
int bsddialog_init_notheme(void)
|
||||
{
|
||||
@ -55,6 +55,7 @@ int bsddialog_init_notheme(void)
|
||||
bsddialog_end();
|
||||
RETURN_ERROR("Cannot init curses (keypad and cursor)");
|
||||
}
|
||||
in_bsddialog_mode = true;
|
||||
|
||||
c = 1;
|
||||
error += start_color();
|
||||
@ -83,6 +84,7 @@ int bsddialog_init(void)
|
||||
|
||||
if (bsddialog_set_default_theme(theme) != 0) {
|
||||
bsddialog_end();
|
||||
in_bsddialog_mode = false;
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
@ -93,15 +95,18 @@ int bsddialog_end(void)
|
||||
{
|
||||
if (endwin() != OK)
|
||||
RETURN_ERROR("Cannot end curses (endwin)");
|
||||
in_bsddialog_mode = false;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
|
||||
{
|
||||
CHECK_PTR(conf);
|
||||
|
||||
move(0, 1);
|
||||
clrtoeol();
|
||||
addstr(backtitle);
|
||||
addstr(CHECK_STR(backtitle));
|
||||
if (conf->no_lines != true)
|
||||
mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
|
||||
SCREENCOLS - 2);
|
||||
@ -111,6 +116,11 @@ int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
bool bsddialog_inmode(void)
|
||||
{
|
||||
return (in_bsddialog_mode);
|
||||
}
|
||||
|
||||
const char *bsddialog_geterror(void)
|
||||
{
|
||||
return (get_error_string());
|
||||
@ -118,25 +128,25 @@ const char *bsddialog_geterror(void)
|
||||
|
||||
int bsddialog_initconf(struct bsddialog_conf *conf)
|
||||
{
|
||||
if (conf == NULL)
|
||||
RETURN_ERROR("conf is NULL");
|
||||
if (sizeof(*conf) != sizeof(struct bsddialog_conf))
|
||||
RETURN_ERROR("Bad conf size");
|
||||
CHECK_PTR(conf);
|
||||
|
||||
memset(conf, 0, sizeof(struct bsddialog_conf));
|
||||
conf->y = BSDDIALOG_CENTER;
|
||||
conf->x = BSDDIALOG_CENTER;
|
||||
conf->shadow = true;
|
||||
conf->text.cols_per_row = COLSPERROW;
|
||||
conf->text.cols_per_row = DEFAULT_COLS_PER_ROW;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_clearterminal(void)
|
||||
void bsddialog_refresh(void)
|
||||
{
|
||||
if (clear() != OK)
|
||||
RETURN_ERROR("Cannot clear the terminal");
|
||||
refresh();
|
||||
}
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
void bsddialog_clear(unsigned int y)
|
||||
{
|
||||
move(y, 0);
|
||||
clrtobot();
|
||||
refresh();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,209 +25,165 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <curses.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
static int
|
||||
message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, const char *text, bool *hastext, struct buttons bs)
|
||||
struct scroll {
|
||||
int ypad; /* y scrollable pad */
|
||||
int htext; /* real h text to draw, to use with htextpad */
|
||||
int htextpad; /* h textpad, draw_dialog() set at least 1 */
|
||||
int printrows; /* h - BORDER - HBUTTONS - BORDER */
|
||||
};
|
||||
|
||||
static void textupdate(struct dialog *d, struct scroll *s)
|
||||
{
|
||||
int htext, wtext;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE ||
|
||||
hastext != NULL) {
|
||||
if (text_size(conf, rows, cols, text, &bs, 0, 1, &htext,
|
||||
&wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (hastext != NULL)
|
||||
*hastext = htext > 0 ? true : false;
|
||||
if (s->htext > 0 && s->htextpad > s->printrows) {
|
||||
wattron(d->widget, t.dialog.arrowcolor);
|
||||
mvwprintw(d->widget, d->h - HBUTTONS - BORDER,
|
||||
d->w - 4 - TEXTHMARGIN - BORDER,
|
||||
"%3d%%", 100 * (s->ypad + s->printrows) / s->htextpad);
|
||||
wattroff(d->widget, t.dialog.arrowcolor);
|
||||
wnoutrefresh(d->widget);
|
||||
}
|
||||
rtextpad(d, s->ypad, 0, 0, HBUTTONS);
|
||||
}
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, wtext, 0, &bs);
|
||||
static int message_size_position(struct dialog *d, int *htext)
|
||||
{
|
||||
int minw;
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 0, true);
|
||||
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 < 0) ? htext : NULL, &d->bs, 0, 0) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
minw = (*htext > 0) ? 1 + TEXTHMARGINS : 0 ;
|
||||
if (widget_checksize(d->h, d->w, &d->bs, MIN(*htext, 1), minw) != 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
|
||||
message_checksize(int rows, int cols, bool hastext, struct buttons bs)
|
||||
static int message_draw(struct dialog *d, struct scroll *s)
|
||||
{
|
||||
int mincols;
|
||||
int unused;
|
||||
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_min_width(bs);
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (message_size_position(d, &s->htext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
|
||||
if (cols < mincols)
|
||||
RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "
|
||||
"for borders, buttons and spaces between buttons");
|
||||
|
||||
if (rows < HBORDERS + 2 /* buttons */)
|
||||
RETURN_ERROR("Msgbox and Yesno need at least 4 rows");
|
||||
if (hastext && rows < HBORDERS + 2 /*buttons*/ + 1 /* text row */)
|
||||
RETURN_ERROR("Msgbox and Yesno with text need at least 5 rows");
|
||||
s->printrows = d->h - BORDER - HBUTTONS - BORDER;
|
||||
s->ypad = 0;
|
||||
getmaxyx(d->textpad, s->htextpad, unused);
|
||||
unused++; /* fix unused error */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
textupdate(WINDOW *widget, WINDOW *textpad, int htextpad, int ytextpad,
|
||||
bool hastext)
|
||||
{
|
||||
int y, x, h, w;
|
||||
|
||||
getbegyx(widget, y, x);
|
||||
getmaxyx(widget, h, w);
|
||||
|
||||
if (hastext && htextpad > h - 4) {
|
||||
wattron(widget, t.dialog.arrowcolor);
|
||||
mvwprintw(widget, h-3, w-6, "%3d%%",
|
||||
100 * (ytextpad+h-4)/ htextpad);
|
||||
wattroff(widget, t.dialog.arrowcolor);
|
||||
wnoutrefresh(widget);
|
||||
}
|
||||
|
||||
pnoutrefresh(textpad, ytextpad, 0, y+1, x+2, y+h-4, x+w-2);
|
||||
}
|
||||
|
||||
static int
|
||||
do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
struct buttons bs)
|
||||
const char *oklabel, const char *cancellabel)
|
||||
{
|
||||
bool hastext, loop;
|
||||
int y, x, h, w, retval, ytextpad, htextpad, printrows, unused;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
bool loop;
|
||||
int retval;
|
||||
wint_t input;
|
||||
struct scroll s;
|
||||
struct dialog d;
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_autosize(conf, rows, cols, &h, &w, text, &hastext, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_checksize(h, w, hastext, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
set_buttons(&d, true, oklabel, cancellabel);
|
||||
s.htext = -1;
|
||||
if(message_draw(&d, &s) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
|
||||
true) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
printrows = h - 4;
|
||||
ytextpad = 0;
|
||||
getmaxyx(textpad, htextpad, unused);
|
||||
unused++; /* fix unused error */
|
||||
loop = true;
|
||||
while (loop) {
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
textupdate(&d, &s);
|
||||
doupdate();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch (input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
retval = bs.value[bs.curr];
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
if (d.conf->key.enable_esc) {
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case '\t': /* TAB */
|
||||
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||
draw_buttons(widget, bs, true);
|
||||
wnoutrefresh(widget);
|
||||
case KEY_RIGHT:
|
||||
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (bs.curr > 0) {
|
||||
bs.curr--;
|
||||
draw_buttons(widget, bs, true);
|
||||
wnoutrefresh(widget);
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (bs.curr < (int)bs.nbuttons - 1) {
|
||||
bs.curr++;
|
||||
draw_buttons(widget, bs, true);
|
||||
wnoutrefresh(widget);
|
||||
}
|
||||
d.bs.curr--;
|
||||
if (d.bs.curr < 0)
|
||||
d.bs.curr = d.bs.nbuttons - 1;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (ytextpad > 0)
|
||||
ytextpad--;
|
||||
if (s.ypad > 0)
|
||||
s.ypad--;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (ytextpad + printrows < htextpad)
|
||||
ytextpad++;
|
||||
if (s.ypad + s.printrows < s.htextpad)
|
||||
s.ypad++;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
ytextpad = 0;
|
||||
s.ypad = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
ytextpad = htextpad - printrows;
|
||||
ytextpad = ytextpad < 0 ? 0 : ytextpad;
|
||||
s.ypad = MAX(s.htextpad - s.printrows, 0);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
ytextpad -= printrows;
|
||||
ytextpad = ytextpad < 0 ? 0 : ytextpad;
|
||||
s.ypad = MAX(s.ypad - s.printrows, 0);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
ytextpad += printrows;
|
||||
if (ytextpad + printrows > htextpad)
|
||||
ytextpad = htextpad - printrows;
|
||||
s.ypad += s.printrows;
|
||||
if (s.ypad + s.printrows > s.htextpad)
|
||||
s.ypad = s.htextpad - s.printrows;
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
if (d.conf->key.f1_file == NULL &&
|
||||
d.conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help(conf) != 0)
|
||||
if (f1help_dialog(d.conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
/* No break, screen size can change */
|
||||
if(message_draw(&d, &s) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
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)
|
||||
if(message_draw(&d, &s) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_autosize(conf, rows, cols, &h, &w, text,
|
||||
NULL, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_checksize(h, w, hastext, 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);
|
||||
|
||||
printrows = h - 4;
|
||||
getmaxyx(textpad, htextpad, unused);
|
||||
ytextpad = 0;
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
|
||||
/* Important to fix grey lines expanding screen */
|
||||
refresh();
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
retval = bs.value[bs.curr];
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
@ -237,20 +193,34 @@ int
|
||||
bsddialog_msgbox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols)
|
||||
{
|
||||
struct buttons bs;
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, NULL);
|
||||
|
||||
return (do_message(conf, text, rows, cols, bs));
|
||||
return (do_message(conf, text, rows, cols, OK_LABEL, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_yesno(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols)
|
||||
{
|
||||
struct buttons bs;
|
||||
return (do_message(conf, text, rows, cols, "Yes", "No"));
|
||||
}
|
||||
|
||||
get_buttons(conf, &bs, "Yes", "No");
|
||||
int
|
||||
bsddialog_infobox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols)
|
||||
{
|
||||
int htext;
|
||||
struct dialog d;
|
||||
|
||||
return (do_message(conf, text, rows, cols, bs));
|
||||
}
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
htext = -1;
|
||||
if (message_size_position(&d, &htext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(&d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
TEXTPAD(&d, 0);
|
||||
doupdate();
|
||||
|
||||
end_dialog(&d);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,166 +25,177 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <curses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
static void
|
||||
updateborders(struct bsddialog_conf *conf, WINDOW *widget, int padmargin,
|
||||
int hpad, int wpad, int ypad, int xpad)
|
||||
struct scrolltext {
|
||||
WINDOW *pad;
|
||||
int ypad;
|
||||
int xpad;
|
||||
int ys;
|
||||
int ye;
|
||||
int xs;
|
||||
int xe;
|
||||
int hpad;
|
||||
int wpad;
|
||||
int margin; /* 2 with multicolumn char, 0 otherwise */
|
||||
int printrows; /* d.h - BORDERS - HBUTTONS */
|
||||
};
|
||||
|
||||
static void updateborders(struct dialog *d, struct scrolltext *st)
|
||||
{
|
||||
int h, w;
|
||||
chtype arrowch, borderch;
|
||||
|
||||
getmaxyx(widget, h, w);
|
||||
|
||||
if (conf->no_lines)
|
||||
if (d->conf->no_lines)
|
||||
borderch = ' ';
|
||||
else if (conf->ascii_lines)
|
||||
else if (d->conf->ascii_lines)
|
||||
borderch = '|';
|
||||
else
|
||||
borderch = ACS_VLINE;
|
||||
|
||||
if (xpad > 0) {
|
||||
arrowch = conf->ascii_lines ? '<' : ACS_LARROW;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.arrowcolor;
|
||||
if (st->xpad > 0) {
|
||||
arrowch = d->conf->ascii_lines ? '<' : ACS_LARROW;
|
||||
arrowch |= t.dialog.arrowcolor;
|
||||
} else {
|
||||
arrowch = borderch;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.lineraisecolor;
|
||||
arrowch |= t.dialog.lineraisecolor;
|
||||
}
|
||||
mvwvline(widget, (h / 2) - 2, 0, arrowch, 4);
|
||||
mvwvline(d->widget, (d->h / 2) - 2, 0, arrowch, 4);
|
||||
|
||||
if (xpad + w-2-padmargin < wpad) {
|
||||
arrowch = conf->ascii_lines ? '>' : ACS_RARROW;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.arrowcolor;
|
||||
if (st->xpad + d->w - 2 - st->margin < st->wpad) {
|
||||
arrowch = d->conf->ascii_lines ? '>' : ACS_RARROW;
|
||||
arrowch |= t.dialog.arrowcolor;
|
||||
} else {
|
||||
arrowch = borderch;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.linelowercolor;
|
||||
arrowch |= t.dialog.linelowercolor;
|
||||
}
|
||||
mvwvline(widget, (h / 2) - 2, w - 1, arrowch, 4);
|
||||
mvwvline(d->widget, (d->h / 2) - 2, d->w - 1, arrowch, 4);
|
||||
|
||||
if (hpad > h - 4) {
|
||||
wattron(widget, t.dialog.arrowcolor);
|
||||
mvwprintw(widget, h-3, w-6, "%3d%%", 100 * (ypad+h-4)/ hpad);
|
||||
wattroff(widget, t.dialog.arrowcolor);
|
||||
if (st->hpad > d->h - 4) {
|
||||
wattron(d->widget, t.dialog.arrowcolor);
|
||||
mvwprintw(d->widget, d->h - 3, d->w - 6,
|
||||
"%3d%%", 100 * (st->ypad + d->h - 4) / st->hpad);
|
||||
wattroff(d->widget, t.dialog.arrowcolor);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
textbox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, int hpad, int wpad, int padmargin, struct buttons bs)
|
||||
static int textbox_size_position(struct dialog *d, struct scrolltext *st)
|
||||
{
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, 0, wpad + padmargin, &bs);
|
||||
int minw;
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, 0, hpad, true);
|
||||
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, NULL, &d->bs, st->hpad, st->wpad + st->margin) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
minw = (st->wpad > 0) ? 2 /*multicolumn char*/ + st->margin : 0 ;
|
||||
if (widget_checksize(d->h, d->w, &d->bs, MIN(st->hpad, 1), minw) != 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
|
||||
textbox_checksize(int rows, int cols, int hpad, struct buttons bs)
|
||||
static int textbox_draw(struct dialog *d, struct scrolltext *st)
|
||||
{
|
||||
int mincols;
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (textbox_size_position(d, st) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_min_width(bs);
|
||||
|
||||
if (cols < mincols)
|
||||
RETURN_ERROR("Few cols for the textbox");
|
||||
|
||||
if (rows < 4 /* HBORDERS + button*/ + (hpad > 0 ? 1 : 0))
|
||||
RETURN_ERROR("Few rows for the textbox");
|
||||
st->ys = d->y + 1;
|
||||
st->xs = (st->margin == 0) ? d->x + 1 : d->x + 2;
|
||||
st->ye = st->ys + d->h - 5;
|
||||
st->xe = st->xs + d->w - 3 - st->margin;
|
||||
st->ypad = st->xpad = 0;
|
||||
st->printrows = d->h-4;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* API */
|
||||
int
|
||||
bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
|
||||
int cols)
|
||||
{
|
||||
bool loop, has_multi_col;
|
||||
int i, retval, y, x, h, w;
|
||||
int hpad, wpad, ypad, xpad, ys, ye, xs, xe, padmargin, printrows;
|
||||
bool loop, has_multicol_ch;
|
||||
int i, retval;
|
||||
unsigned int defaulttablen, linecols;
|
||||
wint_t input;
|
||||
char buf[BUFSIZ];
|
||||
FILE *fp;
|
||||
struct buttons bs;
|
||||
WINDOW *shadow, *widget, *pad;
|
||||
struct scrolltext st;
|
||||
struct dialog d;
|
||||
|
||||
if (file == NULL)
|
||||
RETURN_ERROR("*file is NULL");
|
||||
if ((fp = fopen(file, "r")) == NULL)
|
||||
RETURN_ERROR("Cannot open file");
|
||||
RETURN_FMTERROR("Cannot open file \"%s\"", file);
|
||||
|
||||
if (prepare_dialog(conf, "" /* fake */, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
set_buttons(&d, true, "EXIT", NULL);
|
||||
|
||||
defaulttablen = TABSIZE;
|
||||
set_tabsize((conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen);
|
||||
hpad = 1;
|
||||
wpad = 1;
|
||||
pad = newpad(hpad, wpad);
|
||||
wbkgd(pad, t.dialog.color);
|
||||
padmargin = 0;
|
||||
if (conf->text.tablen > 0)
|
||||
set_tabsize(conf->text.tablen);
|
||||
st.hpad = 1;
|
||||
st.wpad = 1;
|
||||
st.pad = newpad(st.hpad, st.wpad);
|
||||
wbkgd(st.pad, t.dialog.color);
|
||||
st.margin = 0;
|
||||
i = 0;
|
||||
while (fgets(buf, BUFSIZ, fp) != NULL) {
|
||||
if (str_props(buf, &linecols, &has_multi_col) != 0)
|
||||
if (str_props(buf, &linecols, &has_multicol_ch) != 0)
|
||||
continue;
|
||||
if ((int)linecols > wpad) {
|
||||
wpad = linecols;
|
||||
wresize(pad, hpad, wpad);
|
||||
if ((int)linecols > st.wpad) {
|
||||
st.wpad = linecols;
|
||||
wresize(st.pad, st.hpad, st.wpad);
|
||||
}
|
||||
if (i > hpad-1) {
|
||||
hpad++;
|
||||
wresize(pad, hpad, wpad);
|
||||
if (i > st.hpad-1) {
|
||||
st.hpad++;
|
||||
wresize(st.pad, st.hpad, st.wpad);
|
||||
}
|
||||
mvwaddstr(pad, i, 0, buf);
|
||||
mvwaddstr(st.pad, i, 0, buf);
|
||||
i++;
|
||||
if (has_multi_col)
|
||||
padmargin = 2;
|
||||
if (has_multicol_ch)
|
||||
st.margin = 2;
|
||||
}
|
||||
fclose(fp);
|
||||
set_tabsize(defaulttablen);
|
||||
set_tabsize(defaulttablen); /* reset because it is curses global */
|
||||
|
||||
get_buttons(conf, &bs, "EXIT", NULL);
|
||||
bs.curr = 0;
|
||||
bs.nbuttons = 1;
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad, padmargin, bs);
|
||||
if (textbox_checksize(h, w, hpad, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
if (textbox_draw(&d, &st) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
if (new_dialog(conf, &shadow, &widget, y, x, h, w, NULL, NULL, &bs,
|
||||
true) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
ys = y + 1;
|
||||
xs = (padmargin == 0) ? x + 1 : x + 2;
|
||||
ye = ys + h - 5;
|
||||
xe = xs + w - 3 - padmargin;
|
||||
ypad = xpad = 0;
|
||||
printrows = h-4;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
updateborders(conf, widget, padmargin, hpad, wpad, ypad, xpad);
|
||||
updateborders(&d, &st);
|
||||
/*
|
||||
* Overflow multicolumn charchter right border:
|
||||
* wnoutrefresh(widget);
|
||||
* pnoutrefresh(pad, ypad, xpad, ys, xs, ye, xe);
|
||||
* doupdate();
|
||||
*/
|
||||
wrefresh(widget);
|
||||
prefresh(pad, ypad, xpad, ys, xs, ye, xe);
|
||||
wrefresh(d.widget);
|
||||
prefresh(st.pad, st.ypad, st.xpad, st.ys, st.xs, st.ye, st.xe);
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
break; /* loop */
|
||||
}
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
@ -197,84 +208,63 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case '\t': /* TAB */
|
||||
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_HOME:
|
||||
ypad = 0;
|
||||
st.ypad = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
ypad = hpad - printrows;
|
||||
ypad = ypad < 0 ? 0 : ypad;
|
||||
st.ypad = MAX(st.hpad - st.printrows, 0);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
ypad -= printrows;
|
||||
ypad = ypad < 0 ? 0 : ypad;
|
||||
st.ypad = MAX(st.ypad - st.printrows, 0);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
ypad += printrows;
|
||||
if (ypad + printrows > hpad)
|
||||
ypad = hpad - printrows;
|
||||
st.ypad += st.printrows;
|
||||
if (st.ypad + st.printrows > st.hpad)
|
||||
st.ypad = st.hpad - st.printrows;
|
||||
break;
|
||||
case '0':
|
||||
xpad = 0;
|
||||
st.xpad = 0;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
case 'h':
|
||||
xpad = xpad > 0 ? xpad - 1 : 0;
|
||||
st.xpad = MAX(st.xpad - 1, 0);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'l':
|
||||
xpad = (xpad + w-2-padmargin) < wpad ? xpad + 1 : xpad;
|
||||
if (st.xpad + d.w - 2 - st.margin < st.wpad)
|
||||
st.xpad++;
|
||||
break;
|
||||
case KEY_UP:
|
||||
case 'k':
|
||||
ypad = ypad > 0 ? ypad - 1 : 0;
|
||||
st.ypad = MAX(st.ypad - 1, 0);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
case'j':
|
||||
ypad = ypad + printrows <= hpad -1 ? ypad + 1 : ypad;
|
||||
if (st.ypad + st.printrows <= st.hpad -1)
|
||||
st.ypad++;
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help(conf) != 0)
|
||||
if (f1help_dialog(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)
|
||||
if (textbox_draw(&d, &st) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
case KEY_RESIZE:
|
||||
if (textbox_draw(&d, &st) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad,
|
||||
padmargin, bs);
|
||||
if (textbox_checksize(h, w, hpad, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
ys = y + 1;
|
||||
xs = (padmargin == 0) ? x + 1 : x + 2;
|
||||
ye = ys + h - 5;
|
||||
xe = xs + w - 3 - padmargin;
|
||||
ypad = xpad = 0;
|
||||
printrows = h - 4;
|
||||
|
||||
if (update_dialog(conf, shadow, widget, y, x, h, w,
|
||||
NULL, NULL, &bs, true) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
/* Important to fix grey lines expanding screen */
|
||||
refresh();
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_dialog(conf, shadow, widget, pad);
|
||||
delwin(st.pad);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,132 +32,104 @@
|
||||
#include "lib_util.h"
|
||||
|
||||
#define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
|
||||
#define WHITE GET_COLOR(COLOR_WHITE, COLOR_BLACK)
|
||||
#define BLACK GET_COLOR(COLOR_WHITE, COLOR_BLACK) | A_REVERSE
|
||||
#define NFLAGS 6
|
||||
|
||||
struct bsddialog_theme t;
|
||||
bool hastermcolors;
|
||||
|
||||
static struct bsddialog_theme bsddialogtheme = {
|
||||
.screen.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||
struct flag_converter {
|
||||
unsigned int public;
|
||||
unsigned int private;
|
||||
};
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = true,
|
||||
.dialog.titlecolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
|
||||
.dialog.lineraisecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.arrowcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
|
||||
|
||||
.menu.f_selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
|
||||
.menu.selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_YELLOW),
|
||||
.menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.f_namecolor = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
|
||||
.menu.namecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.namesepcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
|
||||
.menu.descsepcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
|
||||
.menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_YELLOW),
|
||||
.menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
.menu.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
|
||||
|
||||
.form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
|
||||
.form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE),
|
||||
.form.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
|
||||
|
||||
.bar.f_color = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
|
||||
.bar.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
|
||||
.button.minmargin = 1,
|
||||
.button.maxmargin = 5,
|
||||
.button.leftdelim = '[',
|
||||
.button.rightdelim = ']',
|
||||
.button.f_delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.button.delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.button.f_color = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
|
||||
.button.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.button.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_YELLOW),
|
||||
.button.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE)
|
||||
static struct flag_converter flagconv[NFLAGS] = {
|
||||
{BSDDIALOG_BLINK, A_BLINK},
|
||||
{BSDDIALOG_BOLD, A_BOLD},
|
||||
{BSDDIALOG_HALFBRIGHT, A_DIM},
|
||||
{BSDDIALOG_HIGHLIGHT, A_STANDOUT},
|
||||
{BSDDIALOG_REVERSE, A_REVERSE},
|
||||
{BSDDIALOG_UNDERLINE, A_UNDERLINE}
|
||||
};
|
||||
|
||||
static struct bsddialog_theme blackwhite = {
|
||||
#define fg COLOR_WHITE
|
||||
#define bk COLOR_BLACK
|
||||
.screen.color = GET_COLOR(fg, bk),
|
||||
.screen.color = WHITE,
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = true,
|
||||
.dialog.titlecolor = GET_COLOR(fg, bk),
|
||||
.dialog.lineraisecolor = GET_COLOR(fg, bk),
|
||||
.dialog.linelowercolor = GET_COLOR(fg, bk),
|
||||
.dialog.color = GET_COLOR(fg, bk),
|
||||
.dialog.bottomtitlecolor = GET_COLOR(fg, bk),
|
||||
.dialog.arrowcolor = GET_COLOR(fg, bk),
|
||||
.dialog.titlecolor = WHITE,
|
||||
.dialog.lineraisecolor = WHITE,
|
||||
.dialog.linelowercolor = WHITE,
|
||||
.dialog.color = WHITE,
|
||||
.dialog.bottomtitlecolor = WHITE,
|
||||
.dialog.arrowcolor = WHITE,
|
||||
|
||||
.menu.f_selectorcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.menu.selectorcolor = GET_COLOR(fg, bk),
|
||||
.menu.f_desccolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.menu.desccolor = GET_COLOR(fg, bk),
|
||||
.menu.f_namecolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.menu.namecolor = GET_COLOR(fg, bk),
|
||||
.menu.namesepcolor = GET_COLOR(fg, bk),
|
||||
.menu.descsepcolor = GET_COLOR(fg, bk),
|
||||
.menu.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
|
||||
.menu.shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE,
|
||||
.menu.bottomdesccolor = GET_COLOR(fg, bk),
|
||||
.menu.f_prefixcolor = WHITE,
|
||||
.menu.prefixcolor = WHITE,
|
||||
.menu.f_selectorcolor = BLACK,
|
||||
.menu.selectorcolor = WHITE,
|
||||
.menu.f_desccolor = BLACK,
|
||||
.menu.desccolor = WHITE,
|
||||
.menu.f_namecolor = BLACK,
|
||||
.menu.namecolor = WHITE,
|
||||
.menu.f_shortcutcolor = BLACK | A_UNDERLINE,
|
||||
.menu.shortcutcolor = WHITE | A_UNDERLINE,
|
||||
.menu.bottomdesccolor = WHITE,
|
||||
.menu.sepnamecolor = WHITE,
|
||||
.menu.sepdesccolor = WHITE,
|
||||
|
||||
.form.f_fieldcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.form.fieldcolor = GET_COLOR(fg, bk),
|
||||
.form.readonlycolor = GET_COLOR(fg, bk),
|
||||
.form.bottomdesccolor = GET_COLOR(fg, bk),
|
||||
.form.f_fieldcolor = BLACK,
|
||||
.form.fieldcolor = WHITE,
|
||||
.form.readonlycolor = WHITE,
|
||||
.form.bottomdesccolor = WHITE,
|
||||
|
||||
.bar.f_color = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.bar.color = GET_COLOR(fg, bk),
|
||||
.bar.f_color = BLACK,
|
||||
.bar.color = WHITE,
|
||||
|
||||
.button.minmargin = 1,
|
||||
.button.maxmargin = 5,
|
||||
.button.leftdelim = '[',
|
||||
.button.rightdelim = ']',
|
||||
.button.f_delimcolor = GET_COLOR(fg, bk),
|
||||
.button.delimcolor = GET_COLOR(fg, bk),
|
||||
.button.f_color = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
|
||||
.button.color = GET_COLOR(fg, bk) | A_UNDERLINE,
|
||||
.button.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
|
||||
.button.shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE
|
||||
.button.f_delimcolor = WHITE,
|
||||
.button.delimcolor = WHITE,
|
||||
.button.f_color = BLACK,
|
||||
.button.color = WHITE,
|
||||
.button.f_shortcutcolor = BLACK | A_UNDERLINE | A_BOLD,
|
||||
.button.shortcutcolor = WHITE | A_UNDERLINE | A_BOLD
|
||||
};
|
||||
|
||||
static struct bsddialog_theme dialogtheme = {
|
||||
static struct bsddialog_theme flat = {
|
||||
.screen.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = false,
|
||||
.dialog.delimtitle = true,
|
||||
.dialog.titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.lineraisecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.arrowcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
|
||||
|
||||
.menu.f_prefixcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.prefixcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.f_selectorcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.menu.selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.menu.f_namecolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.menu.namecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
|
||||
.menu.namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
.menu.descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
.menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_BLUE),
|
||||
.menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
.menu.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.menu.sepnamecolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
.menu.sepdesccolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||
|
||||
.form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
.form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||
@ -169,8 +141,8 @@ static struct bsddialog_theme dialogtheme = {
|
||||
|
||||
.button.minmargin = 1,
|
||||
.button.maxmargin = 5,
|
||||
.button.leftdelim = '<',
|
||||
.button.rightdelim = '>',
|
||||
.button.leftdelim = '[',
|
||||
.button.rightdelim = ']',
|
||||
.button.f_delimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
.button.delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.button.f_color = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD,
|
||||
@ -196,17 +168,19 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
|
||||
dst->dialog.bottomtitlecolor = src->dialog.bottomtitlecolor;
|
||||
dst->dialog.arrowcolor = src->dialog.arrowcolor;
|
||||
|
||||
dst->menu.f_prefixcolor = src->menu.f_prefixcolor;
|
||||
dst->menu.prefixcolor = src->menu.prefixcolor;
|
||||
dst->menu.f_selectorcolor = src->menu.f_selectorcolor;
|
||||
dst->menu.selectorcolor = src->menu.selectorcolor;
|
||||
dst->menu.f_desccolor = src->menu.f_desccolor;
|
||||
dst->menu.desccolor = src->menu.desccolor;
|
||||
dst->menu.f_namecolor = src->menu.f_namecolor;
|
||||
dst->menu.namecolor = src->menu.namecolor;
|
||||
dst->menu.namesepcolor = src->menu.namesepcolor;
|
||||
dst->menu.descsepcolor = src->menu.descsepcolor;
|
||||
dst->menu.f_shortcutcolor = src->menu.f_shortcutcolor;
|
||||
dst->menu.shortcutcolor = src->menu.shortcutcolor;
|
||||
dst->menu.bottomdesccolor = src->menu.bottomdesccolor;
|
||||
dst->menu.sepnamecolor = src->menu.sepnamecolor;
|
||||
dst->menu.sepdesccolor = src->menu.sepdesccolor;
|
||||
|
||||
dst->form.f_fieldcolor = src->form.f_fieldcolor;
|
||||
dst->form.fieldcolor = src->form.fieldcolor;
|
||||
@ -228,17 +202,12 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
|
||||
dst->button.shortcutcolor = src->button.shortcutcolor;
|
||||
|
||||
bkgd(dst->screen.color);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/* API */
|
||||
int bsddialog_get_theme(struct bsddialog_theme *theme)
|
||||
{
|
||||
if (theme == NULL)
|
||||
RETURN_ERROR("theme is NULL");
|
||||
if (sizeof(*theme) != sizeof(struct bsddialog_theme))
|
||||
RETURN_ERROR("Bad suze struct bsddialog_theme");
|
||||
|
||||
CHECK_PTR(theme);
|
||||
set_theme(theme, &t);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
@ -246,34 +215,31 @@ int bsddialog_get_theme(struct bsddialog_theme *theme)
|
||||
|
||||
int bsddialog_set_theme(struct bsddialog_theme *theme)
|
||||
{
|
||||
if (theme == NULL)
|
||||
RETURN_ERROR("theme is NULL");
|
||||
if (sizeof(*theme) != sizeof(struct bsddialog_theme))
|
||||
RETURN_ERROR("Bad size struct bsddialog_theme");
|
||||
|
||||
CHECK_PTR(theme);
|
||||
set_theme(&t, theme);
|
||||
refresh();
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
|
||||
{
|
||||
if (newtheme == BSDDIALOG_THEME_FLAT) {
|
||||
bsddialog_set_theme(&dialogtheme);
|
||||
t.dialog.lineraisecolor = t.dialog.linelowercolor;
|
||||
t.dialog.delimtitle = true;
|
||||
t.button.leftdelim = '[';
|
||||
t.button.rightdelim = ']';
|
||||
t.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE);
|
||||
if (newtheme == BSDDIALOG_THEME_3D) {
|
||||
set_theme(&t, &flat);
|
||||
t.dialog.lineraisecolor =
|
||||
GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD;
|
||||
t.dialog.delimtitle = false;
|
||||
t.dialog.bottomtitlecolor = t.dialog.bottomtitlecolor | A_BOLD;
|
||||
} else if (newtheme == BSDDIALOG_THEME_BLACKWHITE) {
|
||||
set_theme(&t, &blackwhite);
|
||||
} else if (newtheme == BSDDIALOG_THEME_FLAT) {
|
||||
set_theme(&t, &flat);
|
||||
} else {
|
||||
RETURN_FMTERROR("Unknown default theme (%d), "
|
||||
"to use enum bsddialog_default_theme",
|
||||
newtheme);
|
||||
}
|
||||
else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
|
||||
bsddialog_set_theme(&bsddialogtheme);
|
||||
else if (newtheme == BSDDIALOG_THEME_BLACKWHITE)
|
||||
bsddialog_set_theme(&blackwhite);
|
||||
else if (newtheme == BSDDIALOG_THEME_DIALOG)
|
||||
bsddialog_set_theme(&dialogtheme);
|
||||
else
|
||||
RETURN_ERROR("Unknow default theme");
|
||||
refresh();
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
@ -282,43 +248,41 @@ int
|
||||
bsddialog_color(enum bsddialog_color foreground,
|
||||
enum bsddialog_color background, unsigned int flags)
|
||||
{
|
||||
unsigned int cursesflags = 0;
|
||||
unsigned int i, f;
|
||||
|
||||
if (flags & BSDDIALOG_BOLD)
|
||||
cursesflags |= A_BOLD;
|
||||
if (flags & BSDDIALOG_REVERSE)
|
||||
cursesflags |= A_REVERSE;
|
||||
if (flags & BSDDIALOG_UNDERLINE)
|
||||
cursesflags |= A_UNDERLINE;
|
||||
f = 0;
|
||||
for (i=0; i < NFLAGS; i++)
|
||||
if (flags & flagconv[i].public)
|
||||
f |= flagconv[i].private;
|
||||
|
||||
return (GET_COLOR(foreground, background) | cursesflags);
|
||||
return (GET_COLOR(foreground, background) | f);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_color_attrs(int color, enum bsddialog_color *foreground,
|
||||
enum bsddialog_color *background, unsigned int *flags)
|
||||
{
|
||||
unsigned int flag;
|
||||
short f, b;
|
||||
short fg, bg;
|
||||
unsigned int i, f;
|
||||
|
||||
flag = 0U;
|
||||
flag |= (color & A_BOLD) ? BSDDIALOG_BOLD : 0U;
|
||||
flag |= (color & A_REVERSE) ? BSDDIALOG_REVERSE : 0U;
|
||||
flag |= (color & A_UNDERLINE) ? BSDDIALOG_UNDERLINE : 0U;
|
||||
if (flags != NULL)
|
||||
*flags = flag;
|
||||
|
||||
if (pair_content(PAIR_NUMBER(color), &f, &b) != OK)
|
||||
if (flags != NULL) {
|
||||
f = 0;
|
||||
for (i=0; i < NFLAGS; i++)
|
||||
if (color & flagconv[i].private)
|
||||
f |= flagconv[i].public;
|
||||
*flags = f;
|
||||
}
|
||||
if (pair_content(PAIR_NUMBER(color), &fg, &bg) != OK)
|
||||
RETURN_ERROR("Cannot get color attributes");
|
||||
if (foreground != NULL)
|
||||
*foreground = f;
|
||||
*foreground = fg;
|
||||
if (background != NULL)
|
||||
*background = b;
|
||||
*background = bg;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
bool bsddialog_hascolors(void)
|
||||
{
|
||||
return hastermcolors;
|
||||
}
|
||||
return (hastermcolors);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
* Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,158 +25,114 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
#define MINWDATE 23 /* 3 windows and their borders */
|
||||
#define MINWTIME 14 /* 3 windows and their borders */
|
||||
#define HBOX 3
|
||||
#define WBOX 4
|
||||
|
||||
struct clock {
|
||||
unsigned int max;
|
||||
unsigned int value;
|
||||
WINDOW *win;
|
||||
};
|
||||
|
||||
static void
|
||||
drawsquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt,
|
||||
const void *value, bool focus)
|
||||
drawsquare(struct bsddialog_conf *conf, WINDOW *win, unsigned int value,
|
||||
bool focus)
|
||||
{
|
||||
int h, l, w;
|
||||
|
||||
getmaxyx(win, h, w);
|
||||
draw_borders(conf, win, h, w, LOWERED);
|
||||
draw_borders(conf, win, LOWERED);
|
||||
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, 1, conf->ascii_lines ? '^' : ACS_UARROW, 2);
|
||||
mvwhline(win, 2, 1, conf->ascii_lines ? 'v' : ACS_DARROW, 2);
|
||||
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));
|
||||
mvwprintw(win, 1, 1, "%02u", value);
|
||||
if (focus)
|
||||
wattroff(win, t.menu.f_namecolor);
|
||||
|
||||
wrefresh(win);
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
static int
|
||||
datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, int minw, const char *text, struct buttons bs)
|
||||
static int timebox_redraw(struct dialog *d, struct clock *c)
|
||||
{
|
||||
int htext, wtext;
|
||||
int y, x;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, &bs, 3, minw, &htext,
|
||||
&wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built) {
|
||||
hide_dialog(d);
|
||||
refresh(); /* Important for decreasing screen */
|
||||
}
|
||||
if (dialog_size_position(d, HBOX, MINWTIME, NULL) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (draw_dialog(d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (d->built)
|
||||
refresh(); /* Important to fix grey lines expanding screen */
|
||||
TEXTPAD(d, HBOX + HBUTTONS);
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, wtext, minw, &bs);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 3 /* windows */, true);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
datetime_checksize(int rows, int cols, int minw, struct buttons bs)
|
||||
{
|
||||
int mincols;
|
||||
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_min_width(bs);
|
||||
mincols = MAX(minw, mincols);
|
||||
|
||||
if (cols < mincols)
|
||||
RETURN_ERROR("Few cols for this timebox/datebox");
|
||||
|
||||
if (rows < 7) /* 2 button + 2 borders + 3 windows */
|
||||
RETURN_ERROR("Few rows for this timebox/datebox, at least 7");
|
||||
y = d->y + d->h - BORDER - HBUTTONS - HBOX;
|
||||
x = d->x + d->w/2 - 7;
|
||||
update_box(d->conf, c[0].win, y, x, HBOX, WBOX, LOWERED);
|
||||
mvwaddch(d->widget, d->h - 5, d->w/2 - 3, ':');
|
||||
update_box(d->conf, c[1].win, y, x += 5, HBOX, WBOX, LOWERED);
|
||||
mvwaddch(d->widget, d->h - 5, d->w/2 + 2, ':');
|
||||
update_box(d->conf, c[2].win, y, x + 5, HBOX, WBOX, LOWERED);
|
||||
wnoutrefresh(d->widget); /* for mvwaddch(':') */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* API */
|
||||
int
|
||||
bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss)
|
||||
{
|
||||
bool loop, focusbuttons;
|
||||
int i, retval, y, x, h, w, sel;
|
||||
int i, retval, sel;
|
||||
wint_t input;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
struct buttons bs;
|
||||
struct myclockstruct {
|
||||
unsigned int max;
|
||||
unsigned int value;
|
||||
WINDOW *win;
|
||||
};
|
||||
|
||||
if (hh == NULL || mm == NULL || ss == NULL)
|
||||
RETURN_ERROR("hh / mm / ss cannot be NULL");
|
||||
|
||||
struct myclockstruct c[3] = {
|
||||
struct dialog d;
|
||||
struct clock c[3] = {
|
||||
{23, *hh, NULL},
|
||||
{59, *mm, NULL},
|
||||
{59, *ss, NULL}
|
||||
};
|
||||
|
||||
for (i = 0 ; i < 3; i++) {
|
||||
if (c[i].value > c[i].max)
|
||||
c[i].value = c[i].max;
|
||||
CHECK_PTR(hh);
|
||||
CHECK_PTR(mm);
|
||||
CHECK_PTR(ss);
|
||||
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
|
||||
for (i=0; i<3; i++) {
|
||||
if ((c[i].win = newwin(1, 1, 1, 1)) == NULL)
|
||||
RETURN_FMTERROR("Cannot build WINDOW for time[%d]", i);
|
||||
wbkgd(c[i].win, t.dialog.color);
|
||||
c[i].value = MIN(c[i].value, c[i].max);
|
||||
}
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
if (timebox_redraw(&d, c) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text,
|
||||
bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_checksize(h, w, MINWTIME, 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-7, x+w-2);
|
||||
doupdate();
|
||||
|
||||
c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 7, 3, 4, LOWERED);
|
||||
mvwaddch(widget, h - 5, w/2 - 3, ':');
|
||||
c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 2, 3, 4, LOWERED);
|
||||
mvwaddch(widget, h - 5, w/2 + 2, ':');
|
||||
c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 3, 3, 4, LOWERED);
|
||||
|
||||
wrefresh(widget);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
for (i = 0; i < 3; i++)
|
||||
drawsquare(conf, c[i].win, "%02d", &c[i].value,
|
||||
sel == i);
|
||||
|
||||
drawsquare(conf, c[i].win, c[i].value, sel == i);
|
||||
doupdate();
|
||||
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];
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -189,49 +145,49 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
case KEY_RIGHT:
|
||||
case '\t': /* TAB */
|
||||
if (focusbuttons) {
|
||||
bs.curr++;
|
||||
focusbuttons = bs.curr < (int)bs.nbuttons ?
|
||||
d.bs.curr++;
|
||||
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
|
||||
true : false;
|
||||
if (focusbuttons == false) {
|
||||
sel = 0;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
d.bs.curr =
|
||||
conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
focusbuttons = sel > 2 ? true : false;
|
||||
if (focusbuttons) {
|
||||
bs.curr = 0;
|
||||
d.bs.curr = 0;
|
||||
}
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (focusbuttons) {
|
||||
bs.curr--;
|
||||
focusbuttons = bs.curr < 0 ? false : true;
|
||||
d.bs.curr--;
|
||||
focusbuttons = d.bs.curr < 0 ? false : true;
|
||||
if (focusbuttons == false) {
|
||||
sel = 2;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
d.bs.curr =
|
||||
conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel--;
|
||||
focusbuttons = sel < 0 ? true : false;
|
||||
if (focusbuttons)
|
||||
bs.curr = (int)bs.nbuttons - 1;
|
||||
d.bs.curr = (int)d.bs.nbuttons - 1;
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
DRAW_BUTTONS(d);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons) {
|
||||
sel = 0;
|
||||
focusbuttons = false;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
} else { c[sel].value = c[sel].value > 0 ?
|
||||
c[sel].value - 1 : c[sel].max;
|
||||
d.bs.curr = conf->button.always_active ? 0 : -1;
|
||||
DRAW_BUTTONS(d);
|
||||
} else {
|
||||
c[sel].value = c[sel].value > 0 ?
|
||||
c[sel].value - 1 : c[sel].max;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
@ -244,297 +200,32 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
if (f1help(conf) != 0)
|
||||
if (f1help_dialog(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
/* No break, screen size can change */
|
||||
if (timebox_redraw(&d, c) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
break;
|
||||
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)
|
||||
if (timebox_redraw(&d, c) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_autosize(conf, rows, cols, &h, &w,
|
||||
MINWTIME, text, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_checksize(h, w, MINWTIME, 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);
|
||||
|
||||
doupdate();
|
||||
|
||||
mvwaddch(widget, h - 5, w/2 - 3, ':');
|
||||
mvwaddch(widget, h - 5, w/2 + 2, ':');
|
||||
wrefresh(widget);
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
|
||||
|
||||
wclear(c[0].win);
|
||||
mvwin(c[0].win, y + h - 6, x + w/2 - 7);
|
||||
wclear(c[1].win);
|
||||
mvwin(c[1].win, y + h - 6, x + w/2 - 2);
|
||||
wclear(c[2].win);
|
||||
mvwin(c[2].win, y + h - 6, x + w/2 + 3);
|
||||
|
||||
/* Important to avoid grey lines expanding screen */
|
||||
refresh();
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
retval = bs.value[bs.curr];
|
||||
if (shortcut_buttons(input, &d.bs)) {
|
||||
DRAW_BUTTONS(d);
|
||||
doupdate();
|
||||
retval = BUTTONVALUE(d.bs);
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == BSDDIALOG_OK) {
|
||||
*hh = c[0].value;
|
||||
*mm = c[1].value;
|
||||
*ss = c[2].value;
|
||||
}
|
||||
*hh = c[0].value;
|
||||
*mm = c[1].value;
|
||||
*ss = c[2].value;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
delwin(c[i].win);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
end_dialog(&d);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd)
|
||||
{
|
||||
bool loop, focusbuttons;
|
||||
int i, retval, y, x, h, w, sel;
|
||||
wint_t input;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
struct buttons bs;
|
||||
struct calendar {
|
||||
int max;
|
||||
int value;
|
||||
WINDOW *win;
|
||||
unsigned int x;
|
||||
};
|
||||
struct month {
|
||||
const char *name;
|
||||
unsigned int days;
|
||||
};
|
||||
|
||||
if (yy == NULL || mm == NULL || dd == NULL)
|
||||
RETURN_ERROR("yy / mm / dd cannot be NULL");
|
||||
|
||||
struct calendar c[3] = {
|
||||
{9999, *yy, NULL, 4 },
|
||||
{12, *mm, NULL, 9 },
|
||||
{31, *dd, NULL, 2 }
|
||||
};
|
||||
|
||||
struct month m[12] = {
|
||||
{ "January", 31 }, { "February", 28 }, { "March", 31 },
|
||||
{ "April", 30 }, { "May", 31 }, { "June", 30 },
|
||||
{ "July", 31 }, { "August", 31 }, { "September", 30 },
|
||||
{ "October", 31 }, { "November", 30 }, { "December", 31 }
|
||||
};
|
||||
|
||||
for (i = 0 ; i < 3; i++) {
|
||||
if (c[i].value > c[i].max)
|
||||
c[i].value = c[i].max;
|
||||
if (c[i].value < 1)
|
||||
c[i].value = 1;
|
||||
}
|
||||
c[2].max = m[c[1].value -1].days;
|
||||
if (c[1].value == 2 && ISLEAP(c[0].value))
|
||||
c[2].max = 29;
|
||||
if (c[2].value > c[2].max)
|
||||
c[2].value = c[2].max;
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text,
|
||||
bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_checksize(h, w, MINWDATE, 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-7, x+w-2);
|
||||
doupdate();
|
||||
|
||||
c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 11, 3, 6, LOWERED);
|
||||
mvwaddch(widget, h - 5, w/2 - 5, '/');
|
||||
c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 4, 3, 11, LOWERED);
|
||||
mvwaddch(widget, h - 5, w/2 + 7, '/');
|
||||
c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 8, 3, 4, LOWERED);
|
||||
|
||||
wrefresh(widget);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
drawsquare(conf, c[0].win, "%4d", &c[0].value, sel == 0);
|
||||
drawsquare(conf, c[1].win, "%9s", m[c[1].value-1].name,
|
||||
sel == 1);
|
||||
drawsquare(conf, c[2].win, "%02d", &c[2].value, 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 KEY_RIGHT:
|
||||
case '\t': /* TAB */
|
||||
if (focusbuttons) {
|
||||
bs.curr++;
|
||||
focusbuttons = bs.curr < (int)bs.nbuttons ?
|
||||
true : false;
|
||||
if (focusbuttons == false) {
|
||||
sel = 0;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
focusbuttons = sel > 2 ? true : false;
|
||||
if (focusbuttons) {
|
||||
bs.curr = 0;
|
||||
}
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (focusbuttons) {
|
||||
bs.curr--;
|
||||
focusbuttons = bs.curr < 0 ? false : true;
|
||||
if (focusbuttons == false) {
|
||||
sel = 2;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel--;
|
||||
focusbuttons = sel < 0 ? true : false;
|
||||
if (focusbuttons)
|
||||
bs.curr = (int)bs.nbuttons - 1;
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons) {
|
||||
sel = 0;
|
||||
focusbuttons = false;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
} else {
|
||||
c[sel].value = c[sel].value > 1 ?
|
||||
c[sel].value - 1 : c[sel].max ;
|
||||
/* if mount change */
|
||||
c[2].max = m[c[1].value -1].days;
|
||||
/* if year change */
|
||||
if (c[1].value == 2 && ISLEAP(c[0].value))
|
||||
c[2].max = 29;
|
||||
/* set new day */
|
||||
if (c[2].value > c[2].max)
|
||||
c[2].value = c[2].max;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (focusbuttons)
|
||||
break;
|
||||
c[sel].value = c[sel].value < c[sel].max ?
|
||||
c[sel].value + 1 : 1;
|
||||
/* if mount change */
|
||||
c[2].max = m[c[1].value -1].days;
|
||||
/* if year change */
|
||||
if (c[1].value == 2 && ISLEAP(c[0].value))
|
||||
c[2].max = 29;
|
||||
/* set new day */
|
||||
if (c[2].value > c[2].max)
|
||||
c[2].value = c[2].max;
|
||||
break;
|
||||
case KEY_F(1):
|
||||
if (conf->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 (datetime_autosize(conf, rows, cols, &h, &w,
|
||||
MINWDATE, text, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (datetime_checksize(h, w, MINWDATE, 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);
|
||||
doupdate();
|
||||
|
||||
mvwaddch(widget, h - 5, w/2 - 5, '/');
|
||||
mvwaddch(widget, h - 5, w/2 + 7, '/');
|
||||
wrefresh(widget);
|
||||
|
||||
prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
|
||||
|
||||
wclear(c[0].win);
|
||||
mvwin(c[0].win, y + h - 6, x + w/2 - 11);
|
||||
wclear(c[1].win);
|
||||
mvwin(c[1].win, y + h - 6, x + w/2 - 4);
|
||||
wclear(c[2].win);
|
||||
mvwin(c[2].win, y + h - 6, x + w/2 + 8);
|
||||
|
||||
/* 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 = c[0].value;
|
||||
*mm = c[1].value;
|
||||
*dd = c[2].value;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
delwin(c[i].win);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (retval);
|
||||
}
|
@ -1,353 +0,0 @@
|
||||
/*-
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#include "util_theme.h"
|
||||
|
||||
static struct bsddialog_theme t;
|
||||
static char title[1024];
|
||||
|
||||
enum typeprop {
|
||||
BOOL,
|
||||
CHAR,
|
||||
INT,
|
||||
UINT,
|
||||
COLOR
|
||||
};
|
||||
|
||||
struct property {
|
||||
const char* name;
|
||||
enum typeprop type;
|
||||
void *value;
|
||||
};
|
||||
|
||||
#define NPROPERTY 38
|
||||
static struct property p[NPROPERTY] = {
|
||||
{ "theme.screen.color", COLOR, &t.screen.color },
|
||||
|
||||
{ "theme.shadow.color", COLOR, &t.shadow.color },
|
||||
{ "theme.shadow.y", UINT, &t.shadow.y },
|
||||
{ "theme.shadow.x", UINT, &t.shadow.x },
|
||||
|
||||
{ "theme.dialog.color", COLOR, &t.dialog.color },
|
||||
{ "theme.dialog.delimtitle", BOOL, &t.dialog.delimtitle },
|
||||
{ "theme.dialog.titlecolor", COLOR, &t.dialog.titlecolor },
|
||||
{ "theme.dialog.lineraisecolor", COLOR, &t.dialog.lineraisecolor },
|
||||
{ "theme.dialog.linelowercolor", COLOR, &t.dialog.linelowercolor },
|
||||
{ "theme.dialog.bottomtitlecolor", COLOR, &t.dialog.bottomtitlecolor },
|
||||
{ "theme.dialog.arrowcolor", COLOR, &t.dialog.arrowcolor },
|
||||
|
||||
{ "theme.menu.f_selectorcolor", COLOR, &t.menu.f_selectorcolor},
|
||||
{ "theme.menu.selectorcolor", COLOR, &t.menu.selectorcolor},
|
||||
{ "theme.menu.f_namecolor", COLOR, &t.menu.f_namecolor},
|
||||
{ "theme.menu.namecolor", COLOR, &t.menu.namecolor},
|
||||
{ "theme.menu.f_desccolor", COLOR, &t.menu.f_desccolor},
|
||||
{ "theme.menu.desccolor", COLOR, &t.menu.desccolor},
|
||||
{ "theme.menu.namesepcolor", COLOR, &t.menu.namesepcolor},
|
||||
{ "theme.menu.descsepcolor", COLOR, &t.menu.descsepcolor},
|
||||
{ "theme.menu.f_shortcutcolor", COLOR, &t.menu.f_shortcutcolor},
|
||||
{ "theme.menu.shortcutcolor", COLOR, &t.menu.shortcutcolor},
|
||||
{ "theme.menu.bottomdesccolor", COLOR, &t.menu.bottomdesccolor},
|
||||
|
||||
{ "theme.form.f_fieldcolor", COLOR, &t.form.f_fieldcolor},
|
||||
{ "theme.form.fieldcolor", COLOR, &t.form.fieldcolor},
|
||||
{ "theme.form.readonlycolor", COLOR, &t.form.readonlycolor},
|
||||
{ "theme.form.bottomdesccolor", COLOR, &t.form.bottomdesccolor},
|
||||
|
||||
{ "theme.bar.f_color", COLOR, &t.bar.f_color},
|
||||
{ "theme.bar.color", COLOR, &t.bar.color},
|
||||
|
||||
{ "theme.button.minmargin", UINT, &t.button.minmargin},
|
||||
{ "theme.button.maxmargin", UINT, &t.button.maxmargin},
|
||||
{ "theme.button.leftdelim", CHAR, &t.button.leftdelim},
|
||||
{ "theme.button.rightdelim", CHAR, &t.button.rightdelim},
|
||||
{ "theme.button.delimcolor", COLOR, &t.button.delimcolor},
|
||||
{ "theme.button.f_delimcolor", COLOR, &t.button.f_delimcolor},
|
||||
{ "theme.button.color", COLOR, &t.button.color},
|
||||
{ "theme.button.f_color", COLOR, &t.button.f_color},
|
||||
{ "theme.button.shortcutcolor", COLOR, &t.button.shortcutcolor},
|
||||
{ "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor}
|
||||
};
|
||||
|
||||
static const char *color[8] = {
|
||||
"black",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white"
|
||||
};
|
||||
|
||||
#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;
|
||||
unsigned int flags;
|
||||
enum bsddialog_color bg, fg;
|
||||
time_t clock;
|
||||
FILE *fp;
|
||||
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
EXIT_FMTERROR("cannot save theme: %s", bsddialog_geterror());
|
||||
|
||||
if(time(&clock) < 0)
|
||||
EXIT_FMTERROR("%s", "cannot save profile getting current time");
|
||||
|
||||
if ((fp = fopen(file, "w")) == NULL)
|
||||
EXIT_FMTERROR("cannot open %s to save profile", file);
|
||||
|
||||
fprintf(fp, "### bsddialog theme - %s", ctime(&clock));
|
||||
fputs("# Refer to bsddialog(3) manual for theme.* properties\n", fp);
|
||||
fprintf(fp, "version %s\n", version);
|
||||
|
||||
for (i = 0; i < NPROPERTY; i++) {
|
||||
switch (p[i].type) {
|
||||
case CHAR:
|
||||
fprintf(fp, "%s %c\n", p[i].name, *((char*)p[i].value));
|
||||
break;
|
||||
case INT:
|
||||
fprintf(fp, "%s %d\n", p[i].name, *((int*)p[i].value));
|
||||
break;
|
||||
case UINT:
|
||||
fprintf(fp, "%s %u\n", p[i].name,
|
||||
*((unsigned int*)p[i].value));
|
||||
break;
|
||||
case BOOL:
|
||||
fprintf(fp, "%s %s\n", p[i].name,
|
||||
*((bool*)p[i].value) ? "true" : "false");
|
||||
break;
|
||||
case COLOR:
|
||||
bsddialog_color_attrs(*(int*)p[i].value, &fg, &bg,
|
||||
&flags);
|
||||
fprintf(fp, "%s %s %s%s%s%s\n",
|
||||
p[i].name, color[fg], color[bg],
|
||||
flags & BSDDIALOG_BOLD ? " bold" : "",
|
||||
flags & BSDDIALOG_REVERSE ? " reverse" : "",
|
||||
flags & BSDDIALOG_UNDERLINE ? " underline" : "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
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;
|
||||
char charvalue, *value;
|
||||
char line[BUFSIZ], name[BUFSIZ], c1[BUFSIZ], c2[BUFSIZ];
|
||||
int i, j, intvalue, flags;
|
||||
unsigned int uintvalue;
|
||||
enum bsddialog_color bg, fg;
|
||||
FILE *fp;
|
||||
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
EXIT_FMTERROR("Cannot get current theme: %s",
|
||||
bsddialog_geterror());
|
||||
|
||||
if((fp = fopen(file, "r")) == NULL)
|
||||
EXIT_FMTERROR("Cannot open theme \"%s\"", file);
|
||||
|
||||
#define EXIT_ERROR(name, error) do { \
|
||||
fclose(fp); \
|
||||
EXIT_FMTERROR("%s for \"%s\"", error, name); \
|
||||
} while (0)
|
||||
|
||||
while(fgets(line, BUFSIZ, fp) != NULL) {
|
||||
if(line[0] == '#' || line[0] == '\n')
|
||||
continue; /* superfluous, only for efficiency */
|
||||
sscanf(line, "%s", name);
|
||||
for (i = 0; i < NPROPERTY; i++) {
|
||||
if (strcmp(name, p[i].name) == 0) {
|
||||
value = &line[strlen(name)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= NPROPERTY) {
|
||||
if (strcmp(name, "version") == 0)
|
||||
continue;
|
||||
EXIT_ERROR(name, "Unknown theme property name");
|
||||
}
|
||||
switch (p[i].type) {
|
||||
case CHAR:
|
||||
while (value[0] == ' ' || value[0] == '\n' ||
|
||||
value[0] == '\0')
|
||||
value++;
|
||||
if (sscanf(value, "%c", &charvalue) != 1)
|
||||
EXIT_ERROR(p[i].name, "Cannot get a char");
|
||||
*((int*)p[i].value) = charvalue;
|
||||
break;
|
||||
case INT:
|
||||
if (sscanf(value, "%d", &intvalue) != 1)
|
||||
EXIT_ERROR(p[i].name, "Cannot get a int");
|
||||
*((int*)p[i].value) = intvalue;
|
||||
break;
|
||||
case UINT:
|
||||
if (sscanf(value, "%u", &uintvalue) != 1)
|
||||
EXIT_ERROR(p[i].name, "Cannot get a uint");
|
||||
*((unsigned int*)p[i].value) = uintvalue;
|
||||
break;
|
||||
case BOOL:
|
||||
boolvalue = (strstr(value, "true") != NULL) ?
|
||||
true :false;
|
||||
*((bool*)p[i].value) = boolvalue;
|
||||
break;
|
||||
case COLOR:
|
||||
if (sscanf(value, "%s %s", c1, c2) != 2)
|
||||
EXIT_ERROR(p[i].name, "Cannot get 2 colors");
|
||||
/* Foreground */
|
||||
for (j = 0; j < 8 ; j++)
|
||||
if ((strstr(c1, color[j])) != NULL)
|
||||
break;
|
||||
if ((fg = j) > 7)
|
||||
EXIT_ERROR(p[i].name, "Bad foreground");
|
||||
/* Background */
|
||||
for (j = 0; j < 8 ; j++)
|
||||
if ((value = strstr(c2, color[j])) != NULL)
|
||||
break;
|
||||
if ((bg = j) > 7)
|
||||
EXIT_ERROR(p[i].name, "Bad background");
|
||||
/* Flags */
|
||||
flags = 0;
|
||||
if (strstr(value, "bold") != NULL)
|
||||
flags |= BSDDIALOG_BOLD;
|
||||
if (strstr(value, "reverse") != NULL)
|
||||
flags |= BSDDIALOG_REVERSE;
|
||||
if (strstr(value, "underline") != NULL)
|
||||
flags |= BSDDIALOG_UNDERLINE;
|
||||
*((int*)p[i].value) = bsddialog_color(fg, bg, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
bsddialog_set_theme(&t);
|
||||
}
|
||||
|
||||
void bikeshed(struct bsddialog_conf *conf)
|
||||
{
|
||||
int margin, i;
|
||||
int colors[8] = {0, 0, 0, 0 ,0 ,0 , 0, 0};
|
||||
enum bsddialog_color col[6];
|
||||
time_t clock;
|
||||
|
||||
time(&clock);
|
||||
srand(clock);
|
||||
|
||||
/* theme */
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
EXIT_FMTERROR("%s", bsddialog_geterror());
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
do {
|
||||
col[i] = rand() % 8;
|
||||
} while (colors[col[i]] == 1);
|
||||
colors[col[i]] = 1;
|
||||
}
|
||||
|
||||
t.screen.color = bsddialog_color(col[4], col[3], 0);
|
||||
|
||||
t.shadow.color = bsddialog_color(col[0], col[0], 0);
|
||||
t.shadow.y = 1,
|
||||
t.shadow.x = 2,
|
||||
|
||||
t.dialog.delimtitle = (rand() % 2 == 0) ? true : false;
|
||||
t.dialog.titlecolor = bsddialog_color(col[3], col[5], 0);
|
||||
t.dialog.lineraisecolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.linelowercolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.color = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.bottomtitlecolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.arrowcolor = bsddialog_color(col[3], col[5], 0);
|
||||
|
||||
t.menu.f_selectorcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.selectorcolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.menu.f_desccolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.desccolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.menu.f_namecolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.namecolor = bsddialog_color(col[3], col[5], 0);
|
||||
t.menu.namesepcolor = bsddialog_color(col[1], col[5], 0);
|
||||
t.menu.descsepcolor = bsddialog_color(col[1], col[5], 0);
|
||||
t.menu.f_shortcutcolor = bsddialog_color(col[1], col[3], 0);
|
||||
t.menu.shortcutcolor = bsddialog_color(col[1], col[5], 0);
|
||||
t.menu.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
|
||||
|
||||
t.form.f_fieldcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.form.fieldcolor = bsddialog_color(col[5], col[4], 0);
|
||||
t.form.readonlycolor = bsddialog_color(col[4], col[5], 0);
|
||||
t.form.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
|
||||
|
||||
t.bar.f_color = bsddialog_color(col[5], col[3], 0);
|
||||
t.bar.color = bsddialog_color(col[3], col[5], 0);
|
||||
|
||||
t.button.minmargin = 1,
|
||||
t.button.maxmargin = 5,
|
||||
t.button.leftdelim = '[',
|
||||
t.button.rightdelim = ']',
|
||||
t.button.f_delimcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.button.delimcolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.button.f_color = bsddialog_color(col[2], col[3], 0);
|
||||
t.button.color = bsddialog_color(col[0], col[5], 0);
|
||||
t.button.f_shortcutcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0);
|
||||
|
||||
if (bsddialog_set_theme(&t))
|
||||
EXIT_FMTERROR("%s", bsddialog_geterror());
|
||||
|
||||
/* conf */
|
||||
conf->button.always_active = (rand() % 2 == 0) ? true : false;
|
||||
if (conf->title != NULL) {
|
||||
memset(title, 0, 1024);
|
||||
margin = rand() % 5;
|
||||
memset(title, ' ', margin);
|
||||
strcpy(title + margin, conf->title);
|
||||
memset(title + strlen(title), ' ', margin);
|
||||
conf->title = title;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BSDDIALOG_UTILITY_THEME_H_
|
||||
#define _BSDDIALOG_UTILITY_THEME_H_
|
||||
|
||||
void savetheme(const char *file, const char *version);
|
||||
void loadtheme(const char *file);
|
||||
void setdeftheme(enum bsddialog_default_theme theme);
|
||||
void bikeshed(struct bsddialog_conf *conf);
|
||||
|
||||
#endif
|
33
contrib/bsddialog/utility/GNUmakefile
Normal file
33
contrib/bsddialog/utility/GNUmakefile
Normal file
@ -0,0 +1,33 @@
|
||||
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT = bsddialog
|
||||
SOURCES = bsddialog.c util_builders.c util_cli.c util_theme.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
ifneq ($(ENABLEDEBUG),)
|
||||
CFLAGS += -g
|
||||
endif
|
||||
CFLAGS += -D_GNU_SOURCE -Wall -Wextra -I$(LIBPATH)
|
||||
|
||||
ifneq ($(DISABLERPATH),)
|
||||
LDFLAGS += -ltinfo -L$(LIBPATH) -lbsddialog
|
||||
else
|
||||
LDFLAGS += -ltinfo -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
|
||||
endif
|
||||
|
||||
RM = rm -f
|
||||
|
||||
all : $(OUTPUT)
|
||||
|
||||
$(OUTPUT): $(OBJECTS)
|
||||
$(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(OUTPUT) *.o *~
|
33
contrib/bsddialog/utility/Makefile
Normal file
33
contrib/bsddialog/utility/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT = bsddialog
|
||||
SOURCES = bsddialog.c util_builders.c util_cli.c util_theme.c
|
||||
OBJECTS = ${SOURCES:.c=.o}
|
||||
|
||||
.if defined(DEBUG)
|
||||
CFLAGS += -g
|
||||
.endif
|
||||
CFLAGS += -I${LIBPATH} -std=gnu99 -Wall -Wextra -Werror
|
||||
|
||||
.if defined(NORPATH)
|
||||
LDFLAGS += -ltinfow -L${LIBPATH} -lbsddialog
|
||||
.else
|
||||
LDFLAGS += -ltinfow -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
|
||||
.endif
|
||||
|
||||
INSTALL = install
|
||||
RM = rm -f
|
||||
|
||||
all : ${OUTPUT}
|
||||
|
||||
${OUTPUT}: ${OBJECTS}
|
||||
${CC} ${LDFLAGS} ${OBJECTS} -o ${.PREFIX}
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
clean:
|
||||
${RM} ${OUTPUT} *.o *~ *.core *.gz
|
@ -1,6 +1,5 @@
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
|
||||
.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -23,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 23, 2022
|
||||
.Dd July 25, 2023
|
||||
.Dt BSDDIALOG 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -31,9 +30,7 @@
|
||||
.Nd TUI dialogs
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Fl Fl help
|
||||
.Nm
|
||||
.Fl Fl version
|
||||
.Fl Fl help | Fl Fl version
|
||||
.Nm
|
||||
.Op Fl Fl option
|
||||
.Fl Fl dialog
|
||||
@ -41,7 +38,9 @@
|
||||
.Ar rows
|
||||
.Ar cols
|
||||
.Op Ar dialog-argument
|
||||
.Op Fl Fl option
|
||||
.Nm
|
||||
\&...
|
||||
.Fl Fl dialog1
|
||||
.Ar ...
|
||||
.Oo Fl Fl and-dialog
|
||||
@ -51,25 +50,31 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm bsddialog
|
||||
utility builds Text User Interface dialogs and widgets: to display messages,
|
||||
to get input and to inform about a computation status.
|
||||
utility builds Text User Interface dialogs and widgets.
|
||||
.Pp
|
||||
The options
|
||||
The option
|
||||
.Fl Fl help
|
||||
and
|
||||
prints a brief list of features and exits.
|
||||
The option
|
||||
.Fl Fl version
|
||||
print the list of options and the version, respectively, then exit.
|
||||
prints the version and exits.
|
||||
The option
|
||||
.Fl Fl and-dialog
|
||||
builds another dialog unless the previous one returns Error, ESC or Cancel.
|
||||
.Pp
|
||||
Each dialog accepts
|
||||
.Ar text
|
||||
is a message printed inside the dialog.
|
||||
to print a message inside,
|
||||
.Ar rows
|
||||
and
|
||||
.Ar cols
|
||||
are the height and width, 0 for autosize and -1 for fullscreen.
|
||||
to set height and width,
|
||||
.Dv 0
|
||||
for autosize and
|
||||
.Dv -1
|
||||
for fullscreen.
|
||||
.Pp
|
||||
The possible input got from the user interface is printed to standard error.
|
||||
The possible input from the user interface is printed to standard error at exit.
|
||||
.Ss Options
|
||||
The following options can change the default behavior of the utility and are
|
||||
common to some dialog.
|
||||
@ -80,18 +85,37 @@ If available set alternate screen mode, see
|
||||
.It Fl Fl ascii-lines
|
||||
Ascii characters to draw lines.
|
||||
.It Fl Fl backtitle Ar backtitle
|
||||
Title on the top side of the screen.
|
||||
Screen title.
|
||||
.It Fl Fl begin-x Ar x
|
||||
Dialog horizontal position, 0 is the left screen side, -1 center.
|
||||
Set dialog horizontal position,
|
||||
.Dv -1
|
||||
center,
|
||||
.Dv 0
|
||||
left screen.
|
||||
.It Fl Fl begin-y Ar y
|
||||
Dialog vertical position, 0 is the top screen side, -1 center.
|
||||
Set dialog vertical position,
|
||||
.Dv -1
|
||||
center,
|
||||
.Dv 0
|
||||
top screen.
|
||||
.It Fl Fl bikeshed
|
||||
Random settings.
|
||||
Colors.
|
||||
Delimiter and margins around the title.
|
||||
Buttons always active or TAB to switch focus with input components, see
|
||||
Colors, title delimiter, button delimiter; see theme features.
|
||||
Title margin.
|
||||
Buttons always active or TAB to switch focus with other components, see
|
||||
.Fl Fl switch-buttons .
|
||||
Zero padding with time or date output.
|
||||
Zero padding with time output; see
|
||||
.Fl Fl time-format .
|
||||
Zero padding with date output; see
|
||||
.Fl Fl date-format .
|
||||
User Interface date format for
|
||||
.Fl Fl datebox ;
|
||||
see
|
||||
.Fl Fl datebox-format .
|
||||
.It Fl Fl cancel-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Dq Cancel
|
||||
button.
|
||||
.It Fl Fl cancel-label Ar label
|
||||
Label for the
|
||||
.Dq Cancel
|
||||
@ -99,41 +123,7 @@ button.
|
||||
.It Fl Fl clear-dialog
|
||||
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
|
||||
Enable highlights for text, the following sequences are considered escapes:
|
||||
.Bl -column -compact
|
||||
.It Dq \eZ0
|
||||
black.
|
||||
.It Dq \eZ1
|
||||
red.
|
||||
.It Dq \eZ2
|
||||
green.
|
||||
.It Dq \eZ3
|
||||
yellow.
|
||||
.It Dq \eZ4
|
||||
blue.
|
||||
.It Dq \eZ5
|
||||
magenta.
|
||||
.It Dq \eZ6
|
||||
cyan.
|
||||
.It Dq \eZ7
|
||||
white.
|
||||
.It Dq \eZr
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZb
|
||||
bold.
|
||||
.It Dq \eZB
|
||||
disable bold.
|
||||
.It Dq \eZu
|
||||
underline.
|
||||
.It Dq \eZU
|
||||
disable underline.
|
||||
.It Dq \eZn
|
||||
restore normal text.
|
||||
.El
|
||||
Clear the screen, wait a dialog if built.
|
||||
.It Fl Fl columns-per-row Ar columns
|
||||
Try to set the number of columns for a row of text with autosizing; default
|
||||
.Dv 10 .
|
||||
@ -144,13 +134,20 @@ also if it constains a
|
||||
.Dq \en ,
|
||||
see
|
||||
.Fl Fl text-unchanged .
|
||||
.It Fl Fl datebox-format Ar format
|
||||
String to customize
|
||||
.Fl Fl datebox
|
||||
interface, possible values:
|
||||
.Dq d/m/y ,
|
||||
.Dq m/y/d ,
|
||||
.Dq y/m/d .
|
||||
.It Fl Fl date-format Ar format
|
||||
String accepted by
|
||||
.Xr strftime 3
|
||||
to customize the output of
|
||||
.Fl Fl datebox
|
||||
and
|
||||
.Fl Fl calendar
|
||||
.Fl Fl calendar .
|
||||
.It Fl Fl default-button Ar label
|
||||
Focus on the button with
|
||||
.Ar label
|
||||
@ -167,48 +164,74 @@ or
|
||||
button on startup.
|
||||
.It Fl Fl disable-esc
|
||||
Disable ESC key to quit.
|
||||
.It Fl Fl esc-return-cancel
|
||||
ESC key returns
|
||||
.Dq Cancel
|
||||
button value.
|
||||
.It Fl Fl error-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Nm
|
||||
errors.
|
||||
.It Fl Fl esc-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Dv ESC
|
||||
key.
|
||||
.It Fl Fl extra-button
|
||||
Add a button with
|
||||
.Dq Extra
|
||||
label.
|
||||
.It Fl Fl extra-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Dq Extra
|
||||
button.
|
||||
.It Fl Fl extra-label Ar label
|
||||
Set
|
||||
.Ar label
|
||||
for the
|
||||
.Dq Extra
|
||||
button.
|
||||
.It Fl Fl generic-button1 Ar label
|
||||
.It Fl Fl left1-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl generic-button2 Ar label
|
||||
.It Fl Fl left1-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl left1-button .
|
||||
.It Fl Fl left2-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl left2-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl left2-button .
|
||||
.It Fl Fl left3-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl left3-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl left3-button .
|
||||
.It Fl Fl help-button
|
||||
Add a button with
|
||||
.Dq Help
|
||||
label.
|
||||
.It Fl Fl help-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Dq Help
|
||||
button.
|
||||
.It Fl Fl help-label Ar label
|
||||
Set
|
||||
.Ar label
|
||||
for
|
||||
.Dq Help
|
||||
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
|
||||
Print also the selected items if the
|
||||
.It Fl Fl help-print-items
|
||||
Print also the selected items or form values if the
|
||||
.Dq Help
|
||||
button is pressed.
|
||||
.It Fl Fl help-print-name
|
||||
Print the name of the focused item if the
|
||||
.Dq Help
|
||||
button is pressed also
|
||||
with
|
||||
.Fl Fl item-bottom-desc .
|
||||
.It Fl Fl hfile Ar filename
|
||||
Open
|
||||
.Ar filename
|
||||
in a Textbox if F1 key is pressed,
|
||||
in a Textbox if F1 key is pressed.
|
||||
.It Fl Fl hline Ar string
|
||||
Dialog subtitle.
|
||||
.It Fl Fl hmsg Ar string
|
||||
@ -220,7 +243,7 @@ Do not exit with unknown options.
|
||||
.It Fl Fl insecure
|
||||
Print
|
||||
.Sq *
|
||||
to hide passwords while typing; whitespace otherwise.
|
||||
to hide passwords while typing, white space 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.
|
||||
@ -234,7 +257,7 @@ Load theme from
|
||||
.It Fl Fl max-input Ar size
|
||||
Maximum length of the input for
|
||||
.Fl Fl inputbox
|
||||
ans
|
||||
and
|
||||
.Fl Fl passwordbox ,
|
||||
default 2048.
|
||||
.It Fl Fl no-cancel
|
||||
@ -242,11 +265,15 @@ Do not show
|
||||
.Dq Cancel
|
||||
button.
|
||||
.It Fl Fl no-descriptions
|
||||
Do not display items desciption, for Checklist, Menu, Radiolist or Treeview.
|
||||
Do not display items desciption, for Checklist, Menu, Radiolist or Treeview;
|
||||
mutually exclusive with
|
||||
.Fl Fl no-names .
|
||||
.It Fl Fl no-lines
|
||||
Do not draw borders and lines.
|
||||
.It Fl Fl no-names
|
||||
Do not display items name, for Checklist, Menu and Radiolist.
|
||||
Do not display items name, for Checklist, Menu and Radiolist; mutually exclusive
|
||||
with
|
||||
.Fl Fl no-descriptions .
|
||||
.It Fl Fl no-ok
|
||||
Do not draw
|
||||
.Dq OK
|
||||
@ -259,30 +286,52 @@ Set
|
||||
for
|
||||
.Dq OK
|
||||
button.
|
||||
.It Fl Fl ok-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Dq Ok
|
||||
button.
|
||||
.It Fl Fl normal-screen
|
||||
If available set normal screen mode, see
|
||||
.Xr terminfo 5 .
|
||||
.It Fl Fl output-fd Ar fd
|
||||
Print input from user interface to the specified file descriptor.
|
||||
.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 white space.
|
||||
.It Fl Fl print-maxsize
|
||||
Screen size.
|
||||
This option can be used without a dialog.
|
||||
.It Fl Fl print-size
|
||||
Print Dialog height and widget at exit.
|
||||
Print dialog height and width at exit.
|
||||
.It Fl Fl print-version
|
||||
Print version.
|
||||
This option can be used without a dialog.
|
||||
.It Fl Fl quoted
|
||||
Quote items in output, default only when necessary.
|
||||
.It Fl Fl right1-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl right1-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl right1-button .
|
||||
.It Fl Fl right2-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl right2-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl right2-button .
|
||||
.It Fl Fl right3-button Ar label
|
||||
Add a button with
|
||||
.Ar label .
|
||||
.It Fl Fl right3-exit-code Ar retval
|
||||
Set an exit code for
|
||||
.Fl Fl right3-button .
|
||||
.It Fl Fl save-theme Ar file
|
||||
Save the current theme.
|
||||
This option can be used without a dialog.
|
||||
.It Fl Fl separate-output
|
||||
Separate selected items with a new line and avoid to quote.
|
||||
Print selected items separated by a new line and avoid to quote.
|
||||
.It Fl Fl shadow
|
||||
Show a pseudo shadow for the dialog, enabled by default.
|
||||
Show a shadow for the dialog, enabled by default.
|
||||
.It Fl Fl single-quoted
|
||||
Use single quote for items in output.
|
||||
.It Fl Fl sleep Ar secs
|
||||
@ -294,7 +343,7 @@ Print input from user interface to standand error, default.
|
||||
.It Fl Fl stdout
|
||||
Print input from user interface to standard output.
|
||||
.It Fl Fl switch-buttons
|
||||
enables focus switching between buttons and input components pressing TAB,
|
||||
Enable focus switching between buttons and input components pressing TAB,
|
||||
otherwise buttons are always active and ENTER key closes the dialog.
|
||||
Suitable for:
|
||||
.Fl Fl form ,
|
||||
@ -314,24 +363,78 @@ with a tab in
|
||||
.It Fl Fl tab-len Ar spaces
|
||||
Number of spaces to print a TAB in
|
||||
.Ar text .
|
||||
.It Fl Fl text-escape
|
||||
Enable escapes in
|
||||
.Ar text :
|
||||
.Bl -column -compact
|
||||
.It Dq \eZ0
|
||||
black.
|
||||
.It Dq \eZ1
|
||||
red.
|
||||
.It Dq \eZ2
|
||||
green.
|
||||
.It Dq \eZ3
|
||||
yellow.
|
||||
.It Dq \eZ4
|
||||
blue.
|
||||
.It Dq \eZ5
|
||||
magenta.
|
||||
.It Dq \eZ6
|
||||
cyan.
|
||||
.It Dq \eZ7
|
||||
white.
|
||||
.It Dq \eZb
|
||||
bold.
|
||||
.It Dq \eZB
|
||||
disable bold.
|
||||
.It Dq \eZd
|
||||
Half bright.
|
||||
.It Dq \eZD
|
||||
disable half bright.
|
||||
.It Dq \eZk
|
||||
Blink.
|
||||
.It Dq \eZK
|
||||
disable blinking.
|
||||
.It Dq \eZr
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZs
|
||||
Highlight.
|
||||
.It Dq \eZS
|
||||
disable highlighting.
|
||||
.It Dq \eZu
|
||||
underline.
|
||||
.It Dq \eZU
|
||||
disable underline.
|
||||
.It Dq \eZn
|
||||
disable each customization.
|
||||
.El
|
||||
.It Fl Fl text-unchanged
|
||||
By default the
|
||||
Disable
|
||||
.Ar text
|
||||
is changed before to be printed.
|
||||
modification.
|
||||
By default
|
||||
.Ar text
|
||||
is changed before to be printed in the dialog.
|
||||
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
|
||||
Set a graphical style: blackwhite, bsddialog, flat or dialog.
|
||||
Set theme, possible values:
|
||||
.Dq 3d ,
|
||||
.Dq blackwhite ,
|
||||
.Dq flat .
|
||||
.It Fl Fl time-format Ar format
|
||||
String accepted by
|
||||
.Xr strftime 3
|
||||
to customize the output of
|
||||
.Fl Fl timebox .
|
||||
.It Fl Fl timeout-exit-code Ar retval
|
||||
Set an exit code value for the
|
||||
.Fl Fl pause
|
||||
timeout.
|
||||
.It Fl Fl title Ar title
|
||||
Dialog title.
|
||||
.El
|
||||
@ -398,7 +501,7 @@ following strings replace
|
||||
until the next
|
||||
.Dq XXX ,
|
||||
the loop ends reading
|
||||
.Dv EOF .
|
||||
.Dq EOF .
|
||||
.It Fl Fl infobox Ar text Ar rows Ar cols
|
||||
Dialog without buttons to display a message and to exit immediately.
|
||||
.It Fl Fl inputbox Ar text Ar rows Ar cols Op Ar init
|
||||
@ -444,11 +547,12 @@ for autosize.
|
||||
Ar miniperc Oc ...
|
||||
Dialog to show a main bar to represent
|
||||
.Ar mainperc
|
||||
from 0 to 100 and some mini bar with a
|
||||
from 0 to 100.
|
||||
Some mini bar with a
|
||||
.Ar minilabel
|
||||
string and a
|
||||
.Ar miniperc
|
||||
with value from 0 and 100 or negative to print a descriptive string: -1
|
||||
with a value from 0 and 100 or negative to print a descriptive string: -1
|
||||
.Dq Succeeded ,
|
||||
-2
|
||||
.Dq Failed ,
|
||||
@ -465,16 +569,19 @@ with value from 0 and 100 or negative to print a descriptive string: -1
|
||||
-8
|
||||
.Dq \&In Progress ,
|
||||
-9
|
||||
a blank line,
|
||||
to hide
|
||||
.Fa miniperc ,
|
||||
-10
|
||||
.Dq N/A ,
|
||||
-11
|
||||
.Dq Pending .
|
||||
.Dq Pending ,
|
||||
otherwise
|
||||
.Dq UNKNOWN .
|
||||
.It Fl Fl msgbox Ar text Ar rows Ar cols
|
||||
Dialog to diplay a message without the
|
||||
.Dq Cancel
|
||||
button.
|
||||
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
|
||||
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
|
||||
@ -486,9 +593,9 @@ Dialog to get a list of passwords, equivalent to
|
||||
.Fl Fl form
|
||||
except typed characters are hidden.
|
||||
.It Fl Fl pause Ar text Ar rows Ar cols Ar seconds
|
||||
Dialog runs until the timeout in
|
||||
Dialog runs until
|
||||
.Ar seconds
|
||||
expires or a button is pressed.
|
||||
timeout expires or a button is pressed.
|
||||
.It Fl Fl radiolist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \
|
||||
Ar status Oc ...
|
||||
Radiolist to select at most an item from a list via the SPACE key.
|
||||
@ -514,8 +621,9 @@ is the default value, the keys UP, DOWN, HOME, END, PAGEUP and PAGEDOWN can
|
||||
change it.
|
||||
.It Fl Fl textbox Ar file Ar rows Ar cols
|
||||
Opens and prints
|
||||
.Ar file
|
||||
the UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate;
|
||||
.Ar file .
|
||||
UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
|
||||
navigate the file, TAB changes button.
|
||||
.Dq OK
|
||||
button is renamed
|
||||
.Dq EXIT .
|
||||
@ -536,8 +644,29 @@ buttons are renamed
|
||||
.Dq Yes
|
||||
and
|
||||
.Dq \&No .
|
||||
UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate the text.
|
||||
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
|
||||
can override their setting.
|
||||
.Bl -tag -width indent
|
||||
.It Ev NO_COLOR
|
||||
If present and not an empty string (regardless of its value) equivalent to
|
||||
.Fl Fl theme Ar blackwhite .
|
||||
.It Ev BSDDIALOG_ERROR , Ev BSDDIALOG_OK , Ev BSDDIALOG_CANCEL , \
|
||||
Ev BSDDIALOG_HELP , Ev BSDDIALOG_EXTRA , Ev BSDDIALOG_TIMEOUT , \
|
||||
Ev BSDDIALOG_ESC , Ev BSDDIALOG_LEFT1 , Ev BSDDIALOG_LEFT2 , \
|
||||
Ev BSDDIALOG_LEFT3 , Ev BSDDIALOG_RIGHT1 , Ev BSDDIALOG_RIGHT2 , \
|
||||
Ev BSDDIALOG_RIGHT3
|
||||
Set exit codes.
|
||||
.It Ev BSDDIALOG_THEMEFILE Ar file
|
||||
Equivalent to
|
||||
.Fl Fl load-theme Ar file .
|
||||
.El
|
||||
.Sh FILES
|
||||
The theme file
|
||||
.Pa $HOME/.bsddialog.conf
|
||||
is read on startup if exists.
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
@ -566,9 +695,17 @@ Timeout.
|
||||
.It 5
|
||||
ESC key.
|
||||
.It 6
|
||||
Generic 1 button.
|
||||
Left1 generic button.
|
||||
.It 7
|
||||
Generic 2 button.
|
||||
Left2 generic button.
|
||||
.It 8
|
||||
Left3 generic button.
|
||||
.It 9
|
||||
Right1 generic button.
|
||||
.It 10
|
||||
Right2 generic button.
|
||||
.It 11
|
||||
Right2 generic button.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
Backtitle, title and message:
|
||||
@ -595,6 +732,7 @@ Multi-dialog:
|
||||
.Pp
|
||||
Bikeshed:
|
||||
.Dl bsddialog --bikeshed --inputbox Example 0 0
|
||||
.Dl bsddialog --bikeshed --datebox Example 0 0
|
||||
.Pp
|
||||
Mixedgauge:
|
||||
.Dl bsddialog --sleep 3 --mixedgauge Example 10 30 60 L1 \*q -1\*q L2 30
|
||||
@ -641,8 +779,10 @@ Obsolete Equivalent
|
||||
--and-widget --and-dialog
|
||||
--calendar <text> 2 <cols> --calendar <text> 0 <cols>
|
||||
--clear --clear-screen
|
||||
--colors --text-escape
|
||||
--defaultno --default-no
|
||||
--exit-label --ok-label
|
||||
--help-status --help-print-items
|
||||
--help-tags --help-print-name
|
||||
--item-help --item-bottom-desc
|
||||
--keep-tite --alternate-screen
|
||||
@ -655,7 +795,9 @@ Obsolete Equivalent
|
||||
--yes-label --ok-label
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr bsddialog 3
|
||||
.Xr bsddialog 3 ,
|
||||
.Xr strftime 3 ,
|
||||
.Xr terminfo 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm bsddialog
|
||||
@ -668,7 +810,7 @@ was written by
|
||||
.Aq Mt asiciliano@FreeBSD.org .
|
||||
.Pp
|
||||
.Nm bsddialog
|
||||
provides a subset of the functionality described in the
|
||||
provides also a subset of the functionality described in the
|
||||
.Nm dialog
|
||||
manual.
|
||||
The following features were reimplemented:
|
||||
@ -757,8 +899,9 @@ Compatibility is not a priority for future development.
|
||||
.An Baptiste Daroussin
|
||||
.Aq Mt bapt@FreeBSD.org ,
|
||||
.An \&Ed Maste
|
||||
.Aq Mt emaste@FreeBSD.org
|
||||
and
|
||||
.Aq Mt emaste@FreeBSD.org ,
|
||||
.An Juraj Lutter
|
||||
.Aq Mt otis@FreeBSD.org
|
||||
and
|
||||
.An Trenton Schulz
|
||||
for suggestions, help, and testing.
|
338
contrib/bsddialog/utility/bsddialog.c
Normal file
338
contrib/bsddialog/utility/bsddialog.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2023 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 <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <term.h>
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define EXITCODE(retval) (exitcodes[retval + 1].value)
|
||||
#define UNUSED_PAR(x) UNUSED_ ## x __attribute__((__unused__))
|
||||
|
||||
static void custom_text(struct options *opt, char *text, char *buf);
|
||||
|
||||
/* Exit codes */
|
||||
struct exitcode {
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
static struct exitcode exitcodes[14] = {
|
||||
{ "BSDDIALOG_ERROR", 255 },
|
||||
{ "BSDDIALOG_OK", 0 },
|
||||
{ "BSDDIALOG_CANCEL", 1 },
|
||||
{ "BSDDIALOG_HELP", 2 },
|
||||
{ "BSDDIALOG_EXTRA", 3 },
|
||||
{ "BSDDIALOG_TIMEOUT", 4 },
|
||||
{ "BSDDIALOG_ESC", 5 },
|
||||
{ "BSDDIALOG_LEFT1", 6 },
|
||||
{ "BSDDIALOG_LEFT2", 7 },
|
||||
{ "BSDDIALOG_LEFT3", 8 },
|
||||
{ "BSDDIALOG_RIGHT1", 9 },
|
||||
{ "BSDDIALOG_RIGHT2", 10 },
|
||||
{ "BSDDIALOG_RIGHT3", 11 },
|
||||
{ "BSDDIALOG_ITEM_HELP", 2 } /* like HELP by default */
|
||||
};
|
||||
|
||||
void set_exit_code(int lib_retval, int exitcode)
|
||||
{
|
||||
exitcodes[lib_retval + 1].value = exitcode;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
void exit_error(bool usage, const char *fmt, ...)
|
||||
{
|
||||
va_list arg_ptr;
|
||||
|
||||
if (bsddialog_inmode())
|
||||
bsddialog_end();
|
||||
printf("Error: ");
|
||||
va_start(arg_ptr, fmt);
|
||||
vprintf(fmt, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
printf(".\n\n");
|
||||
if (usage) {
|
||||
printf("See \'bsddialog --help\' or \'man 1 bsddialog\' ");
|
||||
printf("for more information.\n");
|
||||
}
|
||||
|
||||
exit (EXITCODE(BSDDIALOG_ERROR));
|
||||
}
|
||||
|
||||
void error_args(const char *dialog, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (bsddialog_inmode())
|
||||
bsddialog_end();
|
||||
printf("Error: %s unexpected argument%s:", dialog, argc > 1 ? "s" : "");
|
||||
for (i = 0; i < argc; i++)
|
||||
printf(" \"%s\"", argv[i]);
|
||||
printf(".\n\n");
|
||||
printf("See \'bsddialog --help\' or \'man 1 bsddialog\' ");
|
||||
printf("for more information.\n");
|
||||
|
||||
exit (EXITCODE(BSDDIALOG_ERROR));
|
||||
}
|
||||
|
||||
/* init */
|
||||
static void sigint_handler(int UNUSED_PAR(sig))
|
||||
{
|
||||
bsddialog_end();
|
||||
|
||||
exit(EXITCODE(BSDDIALOG_ERROR));
|
||||
}
|
||||
|
||||
static void start_bsddialog_mode(void)
|
||||
{
|
||||
if (bsddialog_inmode())
|
||||
return;
|
||||
if (bsddialog_init() != BSDDIALOG_OK)
|
||||
exit_error(false, bsddialog_geterror());
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
}
|
||||
|
||||
static void getenv_exitcodes(void)
|
||||
{
|
||||
int i;
|
||||
int value;
|
||||
char *envvalue;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
envvalue = getenv(exitcodes[i].name);
|
||||
if (envvalue == NULL || envvalue[0] == '\0')
|
||||
continue;
|
||||
value = (int)strtol(envvalue, NULL, 10);
|
||||
exitcodes[i].value = value;
|
||||
/* ITEM_HELP follows HELP without explicit setting */
|
||||
if(i == BSDDIALOG_HELP + 1)
|
||||
exitcodes[BSDDIALOG_ITEM_HELP + 1].value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bsddialog utility: TUI widgets and dialogs.
|
||||
*/
|
||||
int main(int argc, char *argv[argc])
|
||||
{
|
||||
bool startup;
|
||||
int i, rows, cols, retval, parsed, nargc, firstoptind;
|
||||
char *text, **nargv, *pn;
|
||||
struct bsddialog_conf conf;
|
||||
struct options opt;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
getenv_exitcodes();
|
||||
firstoptind = optind;
|
||||
pn = argv[0];
|
||||
retval = BSDDIALOG_OK;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--version") == 0) {
|
||||
printf("Version: %s\n", LIBBSDDIALOG_VERSION);
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
if (strcmp(argv[i], "--help") == 0) {
|
||||
usage();
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
}
|
||||
|
||||
startup = true;
|
||||
while (true) {
|
||||
parsed = parseargs(argc, argv, &conf, &opt);
|
||||
nargc = argc - parsed;
|
||||
nargv = argv + parsed;
|
||||
argc = parsed - optind;
|
||||
argv += optind;
|
||||
|
||||
if (opt.mandatory_dialog && opt.dialogbuilder == NULL)
|
||||
exit_error(true, "expected a --<dialog>");
|
||||
|
||||
if (opt.dialogbuilder == NULL && argc > 0)
|
||||
error_args("(no --<dialog>)", argc, argv);
|
||||
|
||||
/* --print-maxsize or --print-version */
|
||||
if (opt.mandatory_dialog == false && opt.clearscreen == false &&
|
||||
opt.savethemefile == NULL && opt.dialogbuilder == NULL) {
|
||||
retval = BSDDIALOG_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* --<dialog>, --save-theme or clear-screen */
|
||||
text = NULL; /* useless inits, fix compiler warnings */
|
||||
rows = BSDDIALOG_AUTOSIZE;
|
||||
cols = BSDDIALOG_AUTOSIZE;
|
||||
if (opt.dialogbuilder != NULL) {
|
||||
if (argc < 3)
|
||||
exit_error(true,
|
||||
"expected <text> <rows> <cols>");
|
||||
if ((text = strdup(argv[0])) == NULL)
|
||||
exit_error(false, "cannot allocate <text>");
|
||||
if (opt.dialogbuilder != textbox_builder)
|
||||
custom_text(&opt, argv[0], text);
|
||||
rows = (int)strtol(argv[1], NULL, 10);
|
||||
cols = (int)strtol(argv[2], NULL, 10);
|
||||
argc -= 3;
|
||||
argv += 3;
|
||||
}
|
||||
|
||||
/* bsddialog terminal mode (first iteration) */
|
||||
start_bsddialog_mode();
|
||||
|
||||
if (opt.screen_mode != NULL) {
|
||||
opt.screen_mode = tigetstr(opt.screen_mode);
|
||||
if (opt.screen_mode != NULL &&
|
||||
opt.screen_mode != (char*)-1) {
|
||||
tputs(opt.screen_mode, 1, putchar);
|
||||
fflush(stdout);
|
||||
bsddialog_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/* theme */
|
||||
if (startup)
|
||||
startuptheme();
|
||||
startup = false;
|
||||
if ((int)opt.theme >= 0)
|
||||
setdeftheme(opt.theme);
|
||||
if (opt.loadthemefile != NULL)
|
||||
loadtheme(opt.loadthemefile, false);
|
||||
if (opt.bikeshed)
|
||||
bikeshed(&conf);
|
||||
if (opt.savethemefile != NULL)
|
||||
savetheme(opt.savethemefile);
|
||||
|
||||
/* backtitle and dialog */
|
||||
if (opt.dialogbuilder == NULL)
|
||||
break;
|
||||
if (opt.backtitle != NULL)
|
||||
if(bsddialog_backtitle(&conf, opt.backtitle))
|
||||
exit_error(false, bsddialog_geterror());
|
||||
retval = opt.dialogbuilder(&conf, text, rows, cols, argc, argv,
|
||||
&opt);
|
||||
free(text);
|
||||
if (retval == BSDDIALOG_ERROR)
|
||||
exit_error(false, bsddialog_geterror());
|
||||
if (conf.get_height != NULL && conf.get_width != NULL)
|
||||
dprintf(opt.output_fd, "DialogSize: %d, %d\n",
|
||||
*conf.get_height, *conf.get_width);
|
||||
if (opt.clearscreen)
|
||||
bsddialog_clear(0);
|
||||
opt.clearscreen = false;
|
||||
/* --and-dialog ends loop with Cancel or ESC */
|
||||
if (retval == BSDDIALOG_CANCEL || retval == BSDDIALOG_ESC)
|
||||
break;
|
||||
argc = nargc;
|
||||
argv = nargv;
|
||||
if (argc <= 0)
|
||||
break;
|
||||
/* prepare next parseargs() call */
|
||||
argc++;
|
||||
argv--;
|
||||
argv[0] = pn;
|
||||
optind = firstoptind;
|
||||
}
|
||||
|
||||
if (bsddialog_inmode()) {
|
||||
/* --clear-screen can be a single option */
|
||||
if (opt.clearscreen)
|
||||
bsddialog_clear(0);
|
||||
bsddialog_end();
|
||||
}
|
||||
/* end bsddialog terminal mode */
|
||||
|
||||
return (EXITCODE(retval));
|
||||
}
|
||||
|
||||
void custom_text(struct options *opt, char *text, char *buf)
|
||||
{
|
||||
bool trim, crwrap;
|
||||
int i, j;
|
||||
|
||||
if (strstr(text, "\\n") == NULL) {
|
||||
/* "hasnl" mode */
|
||||
trim = true;
|
||||
crwrap = true;
|
||||
} else {
|
||||
trim = false;
|
||||
crwrap = opt->cr_wrap;
|
||||
}
|
||||
if (opt->text_unchanged) {
|
||||
trim = false;
|
||||
crwrap = true;
|
||||
}
|
||||
|
||||
i = j = 0;
|
||||
while (text[i] != '\0') {
|
||||
switch (text[i]) {
|
||||
case '\\':
|
||||
buf[j] = '\\';
|
||||
switch (text[i+1]) {
|
||||
case 'n': /* implicitly in "hasnl" mode */
|
||||
buf[j] = '\n';
|
||||
i++;
|
||||
if (text[i+1] == '\n')
|
||||
i++;
|
||||
break;
|
||||
case 't':
|
||||
if (opt->tab_escape) {
|
||||
buf[j] = '\t';
|
||||
} else {
|
||||
j++;
|
||||
buf[j] = 't';
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
buf[j] = crwrap ? '\n' : ' ';
|
||||
break;
|
||||
case '\t':
|
||||
buf[j] = opt->text_unchanged ? '\t' : ' ';
|
||||
break;
|
||||
default:
|
||||
buf[j] = text[i];
|
||||
}
|
||||
i++;
|
||||
if (!trim || buf[j] != ' ' || j == 0 || buf[j-1] != ' ')
|
||||
j++;
|
||||
}
|
||||
buf[j] = '\0';
|
||||
}
|
125
contrib/bsddialog/utility/util.h
Normal file
125
contrib/bsddialog/utility/util.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2023 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.
|
||||
*/
|
||||
|
||||
#ifndef _BSDDIALOG_UTIL_H_
|
||||
#define _BSDDIALOG_UTIL_H_
|
||||
|
||||
/*
|
||||
* Exit codes and errors, bsddialog.c
|
||||
*/
|
||||
#define BSDDIALOG_ITEM_HELP 12
|
||||
|
||||
void set_exit_code(int lib_retval, int exitcode);
|
||||
void exit_error(bool usage, const char *fmt, ...);
|
||||
void error_args(const char *dialog, int argc, char **argv);
|
||||
|
||||
/*
|
||||
* Command Line, util_cli.c
|
||||
*/
|
||||
struct options {
|
||||
/* Menus options */
|
||||
bool item_always_quote;
|
||||
char *item_default;
|
||||
bool item_depth;
|
||||
char *item_output_sep;
|
||||
bool item_output_sepnl;
|
||||
bool item_prefix;
|
||||
bool item_singlequote;
|
||||
/* Menus and Forms options */
|
||||
bool help_print_item_name;
|
||||
bool help_print_items;
|
||||
bool item_bottomdesc;
|
||||
/* Forms options */
|
||||
int unsigned max_input_form;
|
||||
/* Date and Time options */
|
||||
char *date_fmt;
|
||||
char *time_fmt;
|
||||
/* General options */
|
||||
int getH;
|
||||
int getW;
|
||||
bool ignore;
|
||||
int output_fd;
|
||||
/* Text option */
|
||||
bool cr_wrap;
|
||||
bool tab_escape;
|
||||
bool text_unchanged;
|
||||
/* Theme and Screen options*/
|
||||
char *backtitle;
|
||||
bool bikeshed;
|
||||
enum bsddialog_default_theme theme;
|
||||
bool clearscreen;
|
||||
char *loadthemefile;
|
||||
char *savethemefile;
|
||||
const char *screen_mode;
|
||||
/* Dialog */
|
||||
bool mandatory_dialog;
|
||||
const char *name;
|
||||
int (*dialogbuilder)(struct bsddialog_conf *conf, char* text, int rows,
|
||||
int cols, int argc, char **argv, struct options *opt);
|
||||
};
|
||||
|
||||
void usage(void);
|
||||
int
|
||||
parseargs(int argc, char **argv, struct bsddialog_conf *conf,
|
||||
struct options *opt);
|
||||
|
||||
/*
|
||||
* Dialogs builders, util_builders.c
|
||||
*/
|
||||
#define BUILDER_ARGS struct bsddialog_conf *conf, char* text, int rows, \
|
||||
int cols, int argc, char **argv, struct options *opt
|
||||
int calendar_builder(BUILDER_ARGS);
|
||||
int checklist_builder(BUILDER_ARGS);
|
||||
int datebox_builder(BUILDER_ARGS);
|
||||
int form_builder(BUILDER_ARGS);
|
||||
int gauge_builder(BUILDER_ARGS);
|
||||
int infobox_builder(BUILDER_ARGS);
|
||||
int inputbox_builder(BUILDER_ARGS);
|
||||
int menu_builder(BUILDER_ARGS);
|
||||
int mixedform_builder(BUILDER_ARGS);
|
||||
int mixedgauge_builder(BUILDER_ARGS);
|
||||
int msgbox_builder(BUILDER_ARGS);
|
||||
int passwordbox_builder(BUILDER_ARGS);
|
||||
int passwordform_builder(BUILDER_ARGS);
|
||||
int pause_builder(BUILDER_ARGS);
|
||||
int radiolist_builder(BUILDER_ARGS);
|
||||
int rangebox_builder(BUILDER_ARGS);
|
||||
int textbox_builder(BUILDER_ARGS);
|
||||
int timebox_builder(BUILDER_ARGS);
|
||||
int treeview_builder(BUILDER_ARGS);
|
||||
int yesno_builder(BUILDER_ARGS);
|
||||
|
||||
/*
|
||||
* Theme, util_theme.c
|
||||
*/
|
||||
void savetheme(const char *file);
|
||||
void loadtheme(const char *file, bool compatibility);
|
||||
void setdeftheme(enum bsddialog_default_theme theme);
|
||||
void bikeshed(struct bsddialog_conf *conf);
|
||||
void startuptheme(void);
|
||||
|
||||
#endif
|
768
contrib/bsddialog/utility/util_builders.c
Normal file
768
contrib/bsddialog/utility/util_builders.c
Normal file
@ -0,0 +1,768 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2023 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define NO_PRINT_VALUES(rv) \
|
||||
(rv == BSDDIALOG_ERROR || rv == BSDDIALOG_CANCEL || rv == BSDDIALOG_ESC)
|
||||
|
||||
/* message */
|
||||
int infobox_builder(BUILDER_ARGS)
|
||||
{
|
||||
if (argc > 0)
|
||||
error_args(opt->name, argc, argv);
|
||||
|
||||
return (bsddialog_infobox(conf, text, rows, cols));
|
||||
}
|
||||
|
||||
int msgbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
if (argc > 0)
|
||||
error_args(opt->name, argc, argv);
|
||||
|
||||
return (bsddialog_msgbox(conf, text, rows, cols));
|
||||
}
|
||||
|
||||
int yesno_builder(BUILDER_ARGS)
|
||||
{
|
||||
if (argc > 0)
|
||||
error_args(opt->name, argc, argv);
|
||||
|
||||
return (bsddialog_yesno(conf, text, rows, cols));
|
||||
}
|
||||
|
||||
/* textbox */
|
||||
int textbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
if (argc > 0)
|
||||
error_args(opt->name, argc, argv);
|
||||
|
||||
return (bsddialog_textbox(conf, text, rows, cols));
|
||||
}
|
||||
|
||||
/* bar */
|
||||
int gauge_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
unsigned int perc;
|
||||
|
||||
perc = 0;
|
||||
if (argc == 1) {
|
||||
perc = (u_int)strtoul(argv[0], NULL, 10);
|
||||
perc = perc > 100 ? 100 : perc;
|
||||
} else if (argc > 1) {
|
||||
error_args(opt->name, argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
output = bsddialog_gauge(conf, text, rows, cols, perc, STDIN_FILENO,
|
||||
"XXX", "EOF");
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int mixedgauge_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, *minipercs;
|
||||
unsigned int i, mainperc, nminibars;
|
||||
const char **minilabels;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "%s missing <mainperc>", opt->name);
|
||||
if (((argc-1) % 2) != 0)
|
||||
exit_error(true,
|
||||
"bad %s pair number [<minilabel> <miniperc>]", opt->name);
|
||||
|
||||
mainperc = (u_int)strtoul(argv[0], NULL, 10);
|
||||
mainperc = mainperc > 100 ? 100 : mainperc;
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
nminibars = argc / 2;
|
||||
if ((minilabels = calloc(nminibars, sizeof(char*))) == NULL)
|
||||
exit_error(false, "Cannot allocate memory for minilabels");
|
||||
if ((minipercs = calloc(nminibars, sizeof(int))) == NULL)
|
||||
exit_error(false, "Cannot allocate memory for minipercs");
|
||||
|
||||
for (i = 0; i < nminibars; i++) {
|
||||
minilabels[i] = argv[i * 2];
|
||||
minipercs[i] = (int)strtol(argv[i * 2 + 1], NULL, 10);
|
||||
}
|
||||
|
||||
output = bsddialog_mixedgauge(conf, text, rows, cols, mainperc,
|
||||
nminibars, minilabels, minipercs);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int pause_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
unsigned int secs;
|
||||
|
||||
if (argc == 0)
|
||||
exit_error(true, "--pause missing <seconds>");
|
||||
if (argc > 1)
|
||||
error_args(opt->name, argc - 1, argv + 1);
|
||||
|
||||
secs = (u_int)strtoul(argv[0], NULL, 10);
|
||||
output = bsddialog_pause(conf, text, rows, cols, &secs);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int rangebox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, min, max, value;
|
||||
|
||||
if (argc < 2)
|
||||
exit_error(true, "--rangebox missing <min> <max> [<init>]");
|
||||
if (argc > 3)
|
||||
error_args("--rangebox", argc - 3, argv + 3);
|
||||
|
||||
min = (int)strtol(argv[0], NULL, 10);
|
||||
max = (int)strtol(argv[1], NULL, 10);
|
||||
|
||||
if (argc == 3) {
|
||||
value = (int)strtol(argv[2], NULL, 10);
|
||||
value = value < min ? min : value;
|
||||
value = value > max ? max : value;
|
||||
} else
|
||||
value = min;
|
||||
|
||||
output = bsddialog_rangebox(conf, text, rows, cols, min, max, &value);
|
||||
if (NO_PRINT_VALUES(output) == false)
|
||||
dprintf(opt->output_fd, "%d", value);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
/* date and time */
|
||||
static int date(BUILDER_ARGS)
|
||||
{
|
||||
int rv;
|
||||
unsigned int yy, mm, dd;
|
||||
time_t cal;
|
||||
struct tm *localtm;
|
||||
char stringdate[1024];
|
||||
|
||||
time(&cal);
|
||||
localtm = localtime(&cal);
|
||||
yy = localtm->tm_year + 1900;
|
||||
mm = localtm->tm_mon + 1;
|
||||
dd = localtm->tm_mday;
|
||||
|
||||
if (argc > 3) {
|
||||
error_args(opt->name, argc - 3, argv + 3);
|
||||
} else if (argc == 3) {
|
||||
/* lib checks/sets max and min */
|
||||
dd = (u_int)strtoul(argv[0], NULL, 10);
|
||||
mm = (u_int)strtoul(argv[1], NULL, 10);
|
||||
yy = (u_int)strtoul(argv[2], NULL, 10);
|
||||
}
|
||||
|
||||
if (strcmp(opt->name, "--datebox") == 0)
|
||||
rv = bsddialog_datebox(conf, text, rows, cols, &yy, &mm, &dd);
|
||||
else
|
||||
rv = bsddialog_calendar(conf, text, rows, cols, &yy, &mm, &dd);
|
||||
if (NO_PRINT_VALUES(rv))
|
||||
return (rv);
|
||||
|
||||
if (opt->date_fmt != NULL) {
|
||||
time(&cal);
|
||||
localtm = localtime(&cal);
|
||||
localtm->tm_year = yy - 1900;
|
||||
localtm->tm_mon = mm - 1;
|
||||
localtm->tm_mday = dd;
|
||||
strftime(stringdate, 1024, opt->date_fmt, localtm);
|
||||
dprintf(opt->output_fd, "%s", stringdate);
|
||||
} else if (opt->bikeshed && ~dd & 1) {
|
||||
dprintf(opt->output_fd, "%u/%u/%u", dd, mm, yy);
|
||||
} else {
|
||||
dprintf(opt->output_fd, "%02u/%02u/%u", dd, mm, yy);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int calendar_builder(BUILDER_ARGS)
|
||||
{
|
||||
/* Use height autosizing with rows = 2. Documented in bsddialog(1).
|
||||
*
|
||||
* f_dialog_calendar_size() in bsdconfig/share/dialog.subr:1352
|
||||
* computes height 2 for `dialog --calendar', called by:
|
||||
* 1) f_dialog_input_expire_password() in
|
||||
* bsdconfig/usermgmt/share/user_input.subr:517 and
|
||||
* 2) f_dialog_input_expire_account() in
|
||||
* bsdconfig/usermgmt/share/user_input.subr:660.
|
||||
*
|
||||
* Then use height autosizing with 2 that is min height like dialog.
|
||||
*/
|
||||
if (rows == 2)
|
||||
rows = 0;
|
||||
|
||||
return (date(conf, text, rows, cols, argc, argv, opt));
|
||||
}
|
||||
|
||||
int datebox_builder(BUILDER_ARGS)
|
||||
{
|
||||
return (date(conf, text, rows, cols, argc, argv, opt));
|
||||
}
|
||||
|
||||
int timebox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
unsigned int hh, mm, ss;
|
||||
time_t clock;
|
||||
struct tm *localtm;
|
||||
char stringtime[1024];
|
||||
|
||||
time(&clock);
|
||||
localtm = localtime(&clock);
|
||||
hh = localtm->tm_hour;
|
||||
mm = localtm->tm_min;
|
||||
ss = localtm->tm_sec;
|
||||
|
||||
if (argc > 3) {
|
||||
error_args("--timebox", argc - 3, argv + 3);
|
||||
} else if (argc == 3) {
|
||||
hh = (u_int)strtoul(argv[0], NULL, 10);
|
||||
mm = (u_int)strtoul(argv[1], NULL, 10);
|
||||
ss = (u_int)strtoul(argv[2], NULL, 10);
|
||||
}
|
||||
|
||||
output = bsddialog_timebox(conf, text, rows, cols, &hh, &mm, &ss);
|
||||
if (NO_PRINT_VALUES(output))
|
||||
return (output);
|
||||
|
||||
if (opt->time_fmt != NULL) {
|
||||
time(&clock);
|
||||
localtm = localtime(&clock);
|
||||
localtm->tm_hour = hh;
|
||||
localtm->tm_min = mm;
|
||||
localtm->tm_sec = ss;
|
||||
strftime(stringtime, 1024, opt->time_fmt, localtm);
|
||||
dprintf(opt->output_fd, "%s", stringtime);
|
||||
} else if (opt->bikeshed && ~ss & 1) {
|
||||
dprintf(opt->output_fd, "%u:%u:%u", hh, mm, ss);
|
||||
} else {
|
||||
dprintf(opt->output_fd, "%02u:%02u:%02u", hh, mm, ss);
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
/* menu */
|
||||
static void
|
||||
get_menu_items(int argc, char **argv, bool setprefix, bool setdepth,
|
||||
bool setname, bool setdesc, bool setstatus, bool sethelp,
|
||||
unsigned int *nitems, struct bsddialog_menuitem **items, int *focusitem,
|
||||
struct options *opt)
|
||||
{
|
||||
unsigned int i, j, sizeitem;
|
||||
|
||||
*focusitem = -1;
|
||||
|
||||
sizeitem = 0;
|
||||
sizeitem += setprefix ? 1 : 0;
|
||||
sizeitem += setdepth ? 1 : 0;
|
||||
sizeitem += setname ? 1 : 0;
|
||||
sizeitem += setdesc ? 1 : 0;
|
||||
sizeitem += setstatus ? 1 : 0;
|
||||
sizeitem += sethelp ? 1 : 0;
|
||||
if ((argc % sizeitem) != 0)
|
||||
exit_error(true, "%s bad arguments items number", opt->name);
|
||||
|
||||
*nitems = argc / sizeitem;
|
||||
*items = calloc(*nitems, sizeof(struct bsddialog_menuitem));
|
||||
if (items == NULL)
|
||||
exit_error(false, "%s cannot allocate items", opt->name);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < *nitems; i++) {
|
||||
(*items)[i].prefix = setprefix ? argv[j++] : "";
|
||||
(*items)[i].depth = setdepth ?
|
||||
(u_int)strtoul(argv[j++], NULL, 0) : 0;
|
||||
(*items)[i].name = setname ? argv[j++] : "";
|
||||
(*items)[i].desc = setdesc ? argv[j++] : "";
|
||||
if (setstatus) {
|
||||
if (strcasecmp(argv[j], "on") == 0)
|
||||
(*items)[i].on = true;
|
||||
else if (strcasecmp(argv[j], "off") == 0)
|
||||
(*items)[i].on = false;
|
||||
else
|
||||
exit_error(true,
|
||||
"\"%s\" (item %i) invalid status \"%s\"",
|
||||
(*items)[i].name, i+1, argv[j]);
|
||||
j++;
|
||||
} else
|
||||
(*items)[i].on = false;
|
||||
(*items)[i].bottomdesc = sethelp ? argv[j++] : "";
|
||||
|
||||
if (opt->item_default != NULL && *focusitem == -1)
|
||||
if (strcmp((*items)[i].name, opt->item_default) == 0)
|
||||
*focusitem = i;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_menu_items(int output, int nitems, struct bsddialog_menuitem *items,
|
||||
int focusitem, struct options *opt)
|
||||
{
|
||||
bool sep, sepbefore, sepafter, sepsecond, toquote, ismenu, ischecklist;
|
||||
int i;
|
||||
char quotech;
|
||||
const char *focusname, *sepstr;
|
||||
|
||||
ismenu = (strcmp(opt->name, "--menu") == 0) ? true : false;
|
||||
ischecklist = (strcmp(opt->name, "--checklist") == 0) ? true : false;
|
||||
sep = false;
|
||||
quotech = opt->item_singlequote ? '\'' : '"';
|
||||
|
||||
if (NO_PRINT_VALUES(output))
|
||||
return;
|
||||
|
||||
if (output == BSDDIALOG_HELP) {
|
||||
dprintf(opt->output_fd, "HELP ");
|
||||
|
||||
if (focusitem >= 0) {
|
||||
focusname = items[focusitem].name;
|
||||
if (opt->item_bottomdesc &&
|
||||
opt->help_print_item_name == false)
|
||||
focusname = items[focusitem].bottomdesc;
|
||||
|
||||
toquote = false;
|
||||
if (strchr(focusname, ' ') != NULL) {
|
||||
toquote = opt->item_always_quote;
|
||||
if (ismenu == false &&
|
||||
opt->item_output_sepnl == false)
|
||||
toquote = true;
|
||||
}
|
||||
if (toquote) {
|
||||
dprintf(opt->output_fd, "%c%s%c",
|
||||
quotech, focusname, quotech);
|
||||
} else
|
||||
dprintf(opt->output_fd, "%s", focusname);
|
||||
}
|
||||
|
||||
if (ismenu || opt->help_print_items == false)
|
||||
return;
|
||||
sep = true;
|
||||
}
|
||||
|
||||
sepbefore = false;
|
||||
sepsecond = false;
|
||||
if ((sepstr = opt->item_output_sep) == NULL) {
|
||||
if (opt->item_output_sepnl)
|
||||
sepstr = "\n";
|
||||
else {
|
||||
sepstr = " ";
|
||||
sepsecond = true;
|
||||
}
|
||||
} else
|
||||
sepbefore = true;
|
||||
|
||||
sepafter = false;
|
||||
if (opt->item_output_sepnl) {
|
||||
sepbefore = false;
|
||||
sepafter = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
if (items[i].on == false)
|
||||
continue;
|
||||
|
||||
if (sep || sepbefore)
|
||||
dprintf(opt->output_fd, "%s", sepstr);
|
||||
sep = false;
|
||||
if (sepsecond)
|
||||
sep = true;
|
||||
|
||||
toquote = false;
|
||||
if (strchr(items[i].name, ' ') != NULL) {
|
||||
toquote = opt->item_always_quote;
|
||||
if (ischecklist && opt->item_output_sepnl == false)
|
||||
toquote = true;
|
||||
}
|
||||
if (toquote)
|
||||
dprintf(opt->output_fd, "%c%s%c",
|
||||
quotech, items[i].name, quotech);
|
||||
else
|
||||
dprintf(opt->output_fd, "%s", items[i].name);
|
||||
|
||||
if (sepafter)
|
||||
dprintf(opt->output_fd, "%s", sepstr);
|
||||
}
|
||||
}
|
||||
|
||||
int checklist_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, focusitem;
|
||||
unsigned int menurows, nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--checklist missing <menurows>");
|
||||
menurows = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
|
||||
true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
|
||||
|
||||
output = bsddialog_checklist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int menu_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, focusitem;
|
||||
unsigned int menurows, nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--menu missing <menurows>");
|
||||
menurows = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
|
||||
true, false, opt->item_bottomdesc, &nitems, &items, &focusitem,
|
||||
opt);
|
||||
|
||||
output = bsddialog_menu(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int radiolist_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, focusitem;
|
||||
unsigned int menurows, nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--radiolist missing <menurows>");
|
||||
menurows = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true,
|
||||
true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
|
||||
|
||||
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int treeview_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, focusitem;
|
||||
unsigned int menurows, nitems;
|
||||
struct bsddialog_menuitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--treeview missing <menurows>");
|
||||
menurows = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
get_menu_items(argc-1, argv+1, opt->item_prefix, true, true, true, true,
|
||||
opt->item_bottomdesc, &nitems, &items, &focusitem, opt);
|
||||
|
||||
conf->menu.no_name = true;
|
||||
conf->menu.align_left = true;
|
||||
|
||||
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
/* form */
|
||||
static void
|
||||
print_form_items(int output, int nitems, struct bsddialog_formitem *items,
|
||||
int focusitem, struct options *opt)
|
||||
{
|
||||
int i;
|
||||
const char *helpname;
|
||||
|
||||
if (NO_PRINT_VALUES(output))
|
||||
return;
|
||||
|
||||
if (output == BSDDIALOG_HELP) {
|
||||
dprintf(opt->output_fd, "HELP");
|
||||
if (focusitem >= 0) {
|
||||
helpname = items[focusitem].label;
|
||||
if (opt->item_bottomdesc &&
|
||||
opt->help_print_item_name == false)
|
||||
helpname = items[focusitem].bottomdesc;
|
||||
dprintf(opt->output_fd, " %s", helpname);
|
||||
}
|
||||
if(opt->help_print_items == false)
|
||||
return;
|
||||
dprintf(opt->output_fd, "\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
dprintf(opt->output_fd, "%s\n", items[i].value);
|
||||
free(items[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
int form_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, fieldlen, valuelen, focusitem;
|
||||
unsigned int i, j, flags, formheight, nitems, sizeitem;
|
||||
struct bsddialog_formitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--form missing <formheight>");
|
||||
formheight = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
sizeitem = opt->item_bottomdesc ? 9 : 8;
|
||||
if (argc % sizeitem != 0)
|
||||
exit_error(true, "--form bad number of arguments items");
|
||||
|
||||
nitems = argc / sizeitem;
|
||||
if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
|
||||
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);
|
||||
|
||||
fieldlen = (int)strtol(argv[j++], NULL, 10);
|
||||
items[i].fieldlen = abs(fieldlen);
|
||||
|
||||
valuelen = (int)strtol(argv[j++], NULL, 10);
|
||||
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
|
||||
|
||||
flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
|
||||
items[i].flags = flags;
|
||||
|
||||
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
|
||||
}
|
||||
|
||||
focusitem = -1;
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items, &focusitem);
|
||||
print_form_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int inputbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
struct bsddialog_formitem item;
|
||||
|
||||
if (argc > 1)
|
||||
error_args("--inputbox", argc - 1, argv + 1);
|
||||
|
||||
item.label = "";
|
||||
item.ylabel = 0;
|
||||
item.xlabel = 0;
|
||||
item.init = argc > 0 ? argv[0] : "";
|
||||
item.yfield = 0;
|
||||
item.xfield = 0;
|
||||
item.fieldlen = 1;
|
||||
item.maxvaluelen = opt->max_input_form;
|
||||
item.flags = BSDDIALOG_FIELDNOCOLOR;
|
||||
item.flags |= BSDDIALOG_FIELDCURSOREND;
|
||||
item.flags |= BSDDIALOG_FIELDEXTEND;
|
||||
item.bottomdesc = "";
|
||||
|
||||
output = bsddialog_form(conf, text, rows, cols, 1, 1, &item, NULL);
|
||||
print_form_items(output, 1, &item, -1, opt);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int mixedform_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, focusitem;
|
||||
unsigned int i, j, formheight, nitems, sizeitem;
|
||||
struct bsddialog_formitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--mixedform missing <formheight>");
|
||||
formheight = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
sizeitem = opt->item_bottomdesc ? 10 : 9;
|
||||
if (argc % sizeitem != 0)
|
||||
exit_error(true, "--mixedform bad number of arguments items");
|
||||
|
||||
nitems = argc / sizeitem;
|
||||
if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
|
||||
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].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++] : "";
|
||||
}
|
||||
|
||||
focusitem = -1;
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items, &focusitem);
|
||||
print_form_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int passwordbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
struct bsddialog_formitem item;
|
||||
|
||||
if (argc > 1)
|
||||
error_args("--passwordbox", argc - 1, argv + 1);
|
||||
|
||||
item.label = "";
|
||||
item.ylabel = 0;
|
||||
item.xlabel = 0;
|
||||
item.init = argc > 0 ? argv[0] : "";
|
||||
item.yfield = 0;
|
||||
item.xfield = 0;
|
||||
item.fieldlen = 1;
|
||||
item.maxvaluelen = opt->max_input_form;
|
||||
item.flags = BSDDIALOG_FIELDHIDDEN;
|
||||
item.flags |= BSDDIALOG_FIELDNOCOLOR;
|
||||
item.flags |= BSDDIALOG_FIELDCURSOREND;
|
||||
item.flags |= BSDDIALOG_FIELDEXTEND;
|
||||
item.bottomdesc = "";
|
||||
|
||||
output = bsddialog_form(conf, text, rows, cols, 1, 1, &item, NULL);
|
||||
print_form_items(output, 1, &item, -1, opt);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
int passwordform_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output, fieldlen, valuelen, focusitem;
|
||||
unsigned int i, j, flags, formheight, nitems, sizeitem;
|
||||
struct bsddialog_formitem *items;
|
||||
|
||||
if (argc < 1)
|
||||
exit_error(true, "--passwordform missing <formheight>");
|
||||
formheight = (u_int)strtoul(argv[0], NULL, 10);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
sizeitem = opt->item_bottomdesc ? 9 : 8;
|
||||
if (argc % sizeitem != 0)
|
||||
exit_error(true, "--passwordform bad arguments items number");
|
||||
|
||||
flags = BSDDIALOG_FIELDHIDDEN;
|
||||
nitems = argc / sizeitem;
|
||||
if ((items = calloc(nitems, sizeof(struct bsddialog_formitem))) == NULL)
|
||||
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);
|
||||
|
||||
fieldlen = (int)strtol(argv[j++], NULL, 10);
|
||||
items[i].fieldlen = abs(fieldlen);
|
||||
|
||||
valuelen = (int)strtol(argv[j++], NULL, 10);
|
||||
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
|
||||
|
||||
flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
|
||||
items[i].flags = flags;
|
||||
|
||||
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
|
||||
}
|
||||
|
||||
focusitem = -1;
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items, &focusitem);
|
||||
print_form_items(output, nitems, items, focusitem, opt);
|
||||
free(items);
|
||||
|
||||
if (output == BSDDIALOG_HELP && opt->item_bottomdesc)
|
||||
output = BSDDIALOG_ITEM_HELP;
|
||||
|
||||
return (output);
|
||||
}
|
841
contrib/bsddialog/utility/util_cli.c
Normal file
841
contrib/bsddialog/utility/util_cli.c
Normal file
@ -0,0 +1,841 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2021-2023 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/ioctl.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
enum OPTS {
|
||||
/* Options */
|
||||
ALTERNATE_SCREEN = '?' + 1,
|
||||
AND_DIALOG,
|
||||
ASCII_LINES,
|
||||
BACKTITLE,
|
||||
BEGIN_X,
|
||||
BEGIN_Y,
|
||||
BIKESHED,
|
||||
CANCEL_EXIT_CODE,
|
||||
CANCEL_LABEL,
|
||||
CLEAR_DIALOG,
|
||||
CLEAR_SCREEN,
|
||||
COLUMNS_PER_ROW,
|
||||
CR_WRAP,
|
||||
DATEBOX_FORMAT,
|
||||
DATE_FORMAT,
|
||||
DEFAULT_BUTTON,
|
||||
DEFAULT_ITEM,
|
||||
DEFAULT_NO,
|
||||
DISABLE_ESC,
|
||||
ERROR_EXIT_CODE,
|
||||
ESC_EXIT_CODE,
|
||||
EXIT_LABEL,
|
||||
EXTRA_BUTTON,
|
||||
EXTRA_EXIT_CODE,
|
||||
EXTRA_LABEL,
|
||||
HELP_BUTTON,
|
||||
HELP_EXIT_CODE,
|
||||
HELP_LABEL,
|
||||
HELP_PRINT_ITEMS,
|
||||
HELP_PRINT_NAME,
|
||||
HFILE,
|
||||
HLINE,
|
||||
HMSG,
|
||||
IGNORE,
|
||||
INSECURE,
|
||||
ITEM_BOTTOM_DESC,
|
||||
ITEM_DEPTH,
|
||||
ITEM_PREFIX,
|
||||
LEFT1_BUTTON,
|
||||
LEFT1_EXIT_CODE,
|
||||
LEFT2_BUTTON,
|
||||
LEFT2_EXIT_CODE,
|
||||
LEFT3_BUTTON,
|
||||
LEFT3_EXIT_CODE,
|
||||
LOAD_THEME,
|
||||
MAX_INPUT,
|
||||
NO_CANCEL,
|
||||
NO_DESCRIPTIONS,
|
||||
NO_LINES,
|
||||
NO_NAMES,
|
||||
NO_OK,
|
||||
NO_SHADOW,
|
||||
NORMAL_SCREEN,
|
||||
OK_EXIT_CODE,
|
||||
OK_LABEL,
|
||||
OUTPUT_FD,
|
||||
OUTPUT_SEPARATOR,
|
||||
PRINT_MAXSIZE,
|
||||
PRINT_SIZE,
|
||||
PRINT_VERSION,
|
||||
QUOTED,
|
||||
RIGHT1_BUTTON,
|
||||
RIGHT1_EXIT_CODE,
|
||||
RIGHT2_BUTTON,
|
||||
RIGHT2_EXIT_CODE,
|
||||
RIGHT3_BUTTON,
|
||||
RIGHT3_EXIT_CODE,
|
||||
SAVE_THEME,
|
||||
SEPARATE_OUTPUT,
|
||||
SHADOW,
|
||||
SINGLE_QUOTED,
|
||||
SLEEP,
|
||||
STDERR,
|
||||
STDOUT,
|
||||
SWITCH_BUTTONS,
|
||||
TAB_ESCAPE,
|
||||
TAB_LEN,
|
||||
TEXT_ESCAPE,
|
||||
TEXT_UNCHANGED,
|
||||
THEME,
|
||||
TIMEOUT_EXIT_CODE,
|
||||
TIME_FORMAT,
|
||||
TITLE,
|
||||
/* Dialogs */
|
||||
CALENDAR,
|
||||
CHECKLIST,
|
||||
DATEBOX,
|
||||
FORM,
|
||||
GAUGE,
|
||||
INFOBOX,
|
||||
INPUTBOX,
|
||||
MENU,
|
||||
MIXEDFORM,
|
||||
MIXEDGAUGE,
|
||||
MSGBOX,
|
||||
PASSWORDBOX,
|
||||
PASSWORDFORM,
|
||||
PAUSE,
|
||||
RADIOLIST,
|
||||
RANGEBOX,
|
||||
TEXTBOX,
|
||||
TIMEBOX,
|
||||
TREEVIEW,
|
||||
YESNO
|
||||
};
|
||||
|
||||
/* options descriptor */
|
||||
static struct option longopts[] = {
|
||||
/* Options */
|
||||
{"alternate-screen", no_argument, NULL, ALTERNATE_SCREEN},
|
||||
{"and-dialog", no_argument, NULL, AND_DIALOG},
|
||||
{"and-widget", no_argument, NULL, AND_DIALOG},
|
||||
{"ascii-lines", no_argument, NULL, ASCII_LINES},
|
||||
{"backtitle", required_argument, NULL, BACKTITLE},
|
||||
{"begin-x", required_argument, NULL, BEGIN_X},
|
||||
{"begin-y", required_argument, NULL, BEGIN_Y},
|
||||
{"bikeshed", no_argument, NULL, BIKESHED},
|
||||
{"cancel-exit-code", required_argument, NULL, CANCEL_EXIT_CODE},
|
||||
{"cancel-label", required_argument, NULL, CANCEL_LABEL},
|
||||
{"clear", no_argument, NULL, CLEAR_SCREEN},
|
||||
{"clear-dialog", no_argument, NULL, CLEAR_DIALOG},
|
||||
{"clear-screen", no_argument, NULL, CLEAR_SCREEN},
|
||||
{"colors", no_argument, NULL, TEXT_ESCAPE},
|
||||
{"columns-per-row", required_argument, NULL, COLUMNS_PER_ROW},
|
||||
{"cr-wrap", no_argument, NULL, CR_WRAP},
|
||||
{"datebox-format", required_argument, NULL, DATEBOX_FORMAT},
|
||||
{"date-format", required_argument, NULL, DATE_FORMAT},
|
||||
{"defaultno", no_argument, NULL, DEFAULT_NO},
|
||||
{"default-button", required_argument, NULL, DEFAULT_BUTTON},
|
||||
{"default-item", required_argument, NULL, DEFAULT_ITEM},
|
||||
{"default-no", no_argument, NULL, DEFAULT_NO},
|
||||
{"disable-esc", no_argument, NULL, DISABLE_ESC},
|
||||
{"error-exit-code", required_argument, NULL, ERROR_EXIT_CODE},
|
||||
{"esc-exit-code", required_argument, NULL, ESC_EXIT_CODE},
|
||||
{"exit-label", required_argument, NULL, EXIT_LABEL},
|
||||
{"extra-button", no_argument, NULL, EXTRA_BUTTON},
|
||||
{"extra-exit-code", required_argument, NULL, EXTRA_EXIT_CODE},
|
||||
{"extra-label", required_argument, NULL, EXTRA_LABEL},
|
||||
{"help-button", no_argument, NULL, HELP_BUTTON},
|
||||
{"help-exit-code", required_argument, NULL, HELP_EXIT_CODE},
|
||||
{"help-label", required_argument, NULL, HELP_LABEL},
|
||||
{"help-print-items", no_argument, NULL, HELP_PRINT_ITEMS},
|
||||
{"help-print-name", no_argument, NULL, HELP_PRINT_NAME},
|
||||
{"help-status", no_argument, NULL, HELP_PRINT_ITEMS},
|
||||
{"help-tags", no_argument, NULL, HELP_PRINT_NAME},
|
||||
{"hfile", required_argument, NULL, HFILE},
|
||||
{"hline", required_argument, NULL, HLINE},
|
||||
{"hmsg", required_argument, NULL, HMSG},
|
||||
{"ignore", no_argument, NULL, IGNORE},
|
||||
{"insecure", no_argument, NULL, INSECURE},
|
||||
{"item-bottom-desc", no_argument, NULL, ITEM_BOTTOM_DESC},
|
||||
{"item-depth", no_argument, NULL, ITEM_DEPTH},
|
||||
{"item-help", no_argument, NULL, ITEM_BOTTOM_DESC},
|
||||
{"item-prefix", no_argument, NULL, ITEM_PREFIX},
|
||||
{"keep-tite", no_argument, NULL, ALTERNATE_SCREEN},
|
||||
{"left1-button", required_argument, NULL, LEFT1_BUTTON},
|
||||
{"left1-exit-code", required_argument, NULL, LEFT1_EXIT_CODE},
|
||||
{"left2-button", required_argument, NULL, LEFT2_BUTTON},
|
||||
{"left2-exit-code", required_argument, NULL, LEFT2_EXIT_CODE},
|
||||
{"left3-button", required_argument, NULL, LEFT3_BUTTON},
|
||||
{"left3-exit-code", required_argument, NULL, LEFT3_EXIT_CODE},
|
||||
{"load-theme", required_argument, NULL, LOAD_THEME},
|
||||
{"max-input", required_argument, NULL, MAX_INPUT},
|
||||
{"no-cancel", no_argument, NULL, NO_CANCEL},
|
||||
{"nocancel", no_argument, NULL, NO_CANCEL},
|
||||
{"no-descriptions", no_argument, NULL, NO_DESCRIPTIONS},
|
||||
{"no-items", no_argument, NULL, NO_DESCRIPTIONS},
|
||||
{"no-label", required_argument, NULL, CANCEL_LABEL},
|
||||
{"no-lines", no_argument, NULL, NO_LINES},
|
||||
{"no-names", no_argument, NULL, NO_NAMES},
|
||||
{"no-ok", no_argument, NULL, NO_OK},
|
||||
{"nook", no_argument, NULL, NO_OK},
|
||||
{"no-shadow", no_argument, NULL, NO_SHADOW},
|
||||
{"no-tags", no_argument, NULL, NO_NAMES},
|
||||
{"normal-screen", no_argument, NULL, NORMAL_SCREEN},
|
||||
{"ok-exit-code", required_argument, NULL, OK_EXIT_CODE},
|
||||
{"ok-label", required_argument, NULL, OK_LABEL},
|
||||
{"output-fd", required_argument, NULL, OUTPUT_FD},
|
||||
{"output-separator", required_argument, NULL, OUTPUT_SEPARATOR},
|
||||
{"print-maxsize", no_argument, NULL, PRINT_MAXSIZE},
|
||||
{"print-size", no_argument, NULL, PRINT_SIZE},
|
||||
{"print-version", no_argument, NULL, PRINT_VERSION},
|
||||
{"quoted", no_argument, NULL, QUOTED},
|
||||
{"right1-button", required_argument, NULL, RIGHT1_BUTTON},
|
||||
{"right1-exit-code", required_argument, NULL, RIGHT1_EXIT_CODE},
|
||||
{"right2-button", required_argument, NULL, RIGHT2_BUTTON},
|
||||
{"right2-exit-code", required_argument, NULL, RIGHT2_EXIT_CODE},
|
||||
{"right3-button", required_argument, NULL, RIGHT3_BUTTON},
|
||||
{"right3-exit-code", required_argument, NULL, RIGHT3_EXIT_CODE},
|
||||
{"save-theme", required_argument, NULL, SAVE_THEME},
|
||||
{"separate-output", no_argument, NULL, SEPARATE_OUTPUT},
|
||||
{"separator", required_argument, NULL, OUTPUT_SEPARATOR},
|
||||
{"shadow", no_argument, NULL, SHADOW},
|
||||
{"single-quoted", no_argument, NULL, SINGLE_QUOTED},
|
||||
{"sleep", required_argument, NULL, SLEEP},
|
||||
{"stderr", no_argument, NULL, STDERR},
|
||||
{"stdout", no_argument, NULL, STDOUT},
|
||||
{"switch-buttons", no_argument, NULL, SWITCH_BUTTONS},
|
||||
{"tab-escape", no_argument, NULL, TAB_ESCAPE},
|
||||
{"tab-len", required_argument, NULL, TAB_LEN},
|
||||
{"text-escape", no_argument, NULL, TEXT_ESCAPE},
|
||||
{"text-unchanged", no_argument, NULL, TEXT_UNCHANGED},
|
||||
{"theme", required_argument, NULL, THEME},
|
||||
{"timeout-exit-code", required_argument, NULL, TIMEOUT_EXIT_CODE},
|
||||
{"time-format", required_argument, NULL, TIME_FORMAT},
|
||||
{"title", required_argument, NULL, TITLE},
|
||||
{"yes-label", required_argument, NULL, OK_LABEL},
|
||||
/* Dialogs */
|
||||
{"calendar", no_argument, NULL, CALENDAR},
|
||||
{"checklist", no_argument, NULL, CHECKLIST},
|
||||
{"datebox", no_argument, NULL, DATEBOX},
|
||||
{"form", no_argument, NULL, FORM},
|
||||
{"gauge", no_argument, NULL, GAUGE},
|
||||
{"infobox", no_argument, NULL, INFOBOX},
|
||||
{"inputbox", no_argument, NULL, INPUTBOX},
|
||||
{"menu", no_argument, NULL, MENU},
|
||||
{"mixedform", no_argument, NULL, MIXEDFORM},
|
||||
{"mixedgauge", no_argument, NULL, MIXEDGAUGE},
|
||||
{"msgbox", no_argument, NULL, MSGBOX},
|
||||
{"passwordbox", no_argument, NULL, PASSWORDBOX},
|
||||
{"passwordform", no_argument, NULL, PASSWORDFORM},
|
||||
{"pause", no_argument, NULL, PAUSE},
|
||||
{"radiolist", no_argument, NULL, RADIOLIST},
|
||||
{"rangebox", no_argument, NULL, RANGEBOX},
|
||||
{"textbox", no_argument, NULL, TEXTBOX},
|
||||
{"timebox", no_argument, NULL, TIMEBOX},
|
||||
{"treeview", no_argument, NULL, TREEVIEW},
|
||||
{"yesno", no_argument, NULL, YESNO},
|
||||
/* END */
|
||||
{ NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("usage: bsddialog --help | --version\n");
|
||||
printf(" bsddialog [--<opt>] --<dialog> <text> <rows> <cols> "
|
||||
"[<arg>] [--<opt>]\n");
|
||||
printf(" bsddialog ... --<dialog1> ... [--and-dialog --<dialog2> "
|
||||
"...] ...\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Options:\n");
|
||||
printf(" --alternate-screen, --ascii-lines, --backtitle <backtitle>,"
|
||||
" --begin-x <x>,\n --begin-y <y>, --bikeshed,"
|
||||
" --cancel-exit-code <retval>, --cancel-label <label>,\n"
|
||||
" --clear-dialog, --clear-screen, --columns-per-row <columns>,"
|
||||
" --cr-wrap,\n --datebox-format d/m/y|m/d/y|y/m/d,"
|
||||
" --date-format <format>,\n --default-button <label>,"
|
||||
" --default-item <name>, --default-no, --disable-esc,\n"
|
||||
" --error-exit-code <retval>, --esc-exit-code <retval>,"
|
||||
" --exit-label <label>,\n --extra-button,"
|
||||
" --extra-exit-code <retval>, --extra-label <label>,\n"
|
||||
" --left1-button <label>, --left1-exit-code <retval>,"
|
||||
" --left2-button <label>,\n --left2-exit-code <retval>,"
|
||||
" --left3-button <label>, --left3-exit-code <retval>,\n"
|
||||
" --help-button, --help-exit-code <retval>, --help-label <label>,\n"
|
||||
" --help-print-items, --help-print-name, --hfile <file>,"
|
||||
" --hline <string>,\n --hmsg <string>, --ignore, --insecure,"
|
||||
" --item-bottom-desc, --item-depth,\n --item-prefix,"
|
||||
" --load-theme <file>, --max-input <size>, --no-cancel,\n"
|
||||
" --no-descriptions, --no-label <label>, --no-lines, --no-names,"
|
||||
" --no-ok,\n --no-shadow, --normal-screen, --ok-exit-code <retval>,"
|
||||
" --ok-label <label>,\n --output-fd <fd>, --output-separator <sep>,"
|
||||
" --print-maxsize, --print-size,\n --print-version, --quoted,"
|
||||
" --right1-button <label>,\n --right1-exit-code <retval>,"
|
||||
" --right2-button <label>,\n --right2-exit-code <retval>,"
|
||||
" --right3-button <label>,\n --right3-exit-code <retval>,"
|
||||
" --save-theme <file>, --separate-output,\n --separator <sep>,"
|
||||
" --shadow, --single-quoted, --sleep <secs>, --stderr,\n --stdout,"
|
||||
" --switch-buttons, --tab-escape, --tab-len <spaces>,"
|
||||
" --text-escape,\n --text-unchanged, --theme 3d|blackwhite|flat,"
|
||||
" --timeout-exit-code <retval>,\n --time-format <format>,"
|
||||
" --title <title>, --yes-label <label>.");
|
||||
printf("\n\n");
|
||||
|
||||
printf("Dialogs:\n");
|
||||
printf(" --calendar <text> <rows> <cols> [<dd> <mm> <yy>]\n");
|
||||
printf(" --checklist <text> <rows> <cols> <menurows> [<name> <desc> "
|
||||
"on|off] ...\n");
|
||||
printf(" --datebox <text> <rows> <cols> [<dd> <mm> <yy>]\n");
|
||||
printf(" --form <text> <rows> <cols> <formrows> [<label> <ylabel> "
|
||||
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters>] "
|
||||
"...\n");
|
||||
printf(" --gauge <text> <rows> <cols> [<perc>]\n");
|
||||
printf(" --infobox <text> <rows> <cols>\n");
|
||||
printf(" --inputbox <text> <rows> <cols> [<init>]\n");
|
||||
printf(" --menu <text> <rows> <cols> <menurows> [<name> <desc>] ...\n");
|
||||
printf(" --mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
|
||||
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters> "
|
||||
"0|1|2] ...\n");
|
||||
printf(" --mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
|
||||
"<miniperc>] ...\n");
|
||||
printf(" --msgbox <text> <rows> <cols>\n");
|
||||
printf(" --passwordbox <text> <rows> <cols> [<init>]\n");
|
||||
printf(" --passwordform <text> <rows> <cols> <formrows> [<label> "
|
||||
"<ylabel> <xlabel> <init> <yfield> <xfield> <fieldlen> "
|
||||
"<maxletters>] ...\n");
|
||||
printf(" --pause <text> <rows> <cols> <secs>\n");
|
||||
printf(" --radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
|
||||
"on|off] ...\n");
|
||||
printf(" --rangebox <text> <rows> <cols> <min> <max> [<init>]\n");
|
||||
printf(" --textbox <file> <rows> <cols>\n");
|
||||
printf(" --timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n");
|
||||
printf(" --treeview <text> <rows> <cols> <menurows> [<depth> <name> "
|
||||
"<desc> on|off] ...\n");
|
||||
printf(" --yesno <text> <rows> <cols>\n");
|
||||
printf("\n");
|
||||
|
||||
printf("See 'man 1 bsddialog' for more information.\n");
|
||||
}
|
||||
|
||||
int
|
||||
parseargs(int argc, char **argv, struct bsddialog_conf *conf,
|
||||
struct options *opt)
|
||||
{
|
||||
int arg, parsed, i;
|
||||
struct winsize ws;
|
||||
|
||||
bsddialog_initconf(conf);
|
||||
conf->key.enable_esc = true;
|
||||
conf->button.always_active = true;
|
||||
|
||||
memset(opt, 0, sizeof(struct options));
|
||||
opt->theme = -1;
|
||||
opt->output_fd = STDERR_FILENO;
|
||||
opt->max_input_form = 2048;
|
||||
opt->mandatory_dialog = true;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--and-dialog") == 0 ||
|
||||
strcmp(argv[i], "--and-widget") == 0) {
|
||||
argc = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
parsed = argc;
|
||||
while ((arg = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
|
||||
switch (arg) {
|
||||
/* Options */
|
||||
case ALTERNATE_SCREEN:
|
||||
opt->screen_mode = "smcup";
|
||||
break;
|
||||
case AND_DIALOG:
|
||||
if (opt->dialogbuilder == NULL)
|
||||
exit_error(true,"--and-dialog without "
|
||||
"previous --<dialog>");
|
||||
break;
|
||||
case ASCII_LINES:
|
||||
conf->ascii_lines = true;
|
||||
break;
|
||||
case BACKTITLE:
|
||||
opt->backtitle = optarg;
|
||||
if (conf->y == BSDDIALOG_CENTER)
|
||||
conf->auto_topmargin = 2;
|
||||
break;
|
||||
case BEGIN_X:
|
||||
conf->x = (int)strtol(optarg, NULL, 10);
|
||||
if (conf->x < BSDDIALOG_CENTER)
|
||||
exit_error(false, "--begin-x %d is < %d",
|
||||
conf->x, BSDDIALOG_CENTER);
|
||||
break;
|
||||
case BEGIN_Y:
|
||||
conf->y = (int)strtol(optarg, NULL, 10);
|
||||
if (conf->y < BSDDIALOG_CENTER)
|
||||
exit_error(false, "--begin-y %d is < %d",
|
||||
conf->y, BSDDIALOG_CENTER);
|
||||
conf->auto_topmargin = 0;
|
||||
break;
|
||||
case BIKESHED:
|
||||
opt->bikeshed = true;
|
||||
break;
|
||||
case CANCEL_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_CANCEL,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case CANCEL_LABEL:
|
||||
conf->button.cancel_label = optarg;
|
||||
break;
|
||||
case CLEAR_DIALOG:
|
||||
conf->clear = true;
|
||||
break;
|
||||
case CLEAR_SCREEN:
|
||||
opt->mandatory_dialog = false;
|
||||
opt->clearscreen = true;
|
||||
break;
|
||||
case COLUMNS_PER_ROW:
|
||||
conf->text.cols_per_row =
|
||||
(u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case CR_WRAP:
|
||||
opt->cr_wrap = true;
|
||||
break;
|
||||
case DATEBOX_FORMAT:
|
||||
if (strcasecmp(optarg, "d/m/y") == 0)
|
||||
conf->date.format = "d/m/y";
|
||||
else if (strcasecmp(optarg, "m/d/y") == 0)
|
||||
conf->date.format = "m/d/y";
|
||||
else if (strcasecmp(optarg, "y/m/d") == 0)
|
||||
conf->date.format = "y/m/d";
|
||||
else
|
||||
exit_error(true,
|
||||
"date format \"%s\" is invalid", optarg);
|
||||
break;
|
||||
case DATE_FORMAT:
|
||||
opt->date_fmt = optarg;
|
||||
break;
|
||||
case DEFAULT_BUTTON:
|
||||
conf->button.default_label = optarg;
|
||||
break;
|
||||
case DEFAULT_ITEM:
|
||||
opt->item_default = optarg;
|
||||
break;
|
||||
case DEFAULT_NO:
|
||||
conf->button.default_cancel = true;
|
||||
break;
|
||||
case DISABLE_ESC:
|
||||
conf->key.enable_esc = false;
|
||||
break;
|
||||
case ERROR_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_ERROR,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case ESC_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_ESC,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case EXIT_LABEL:
|
||||
conf->button.ok_label = optarg;
|
||||
break;
|
||||
case EXTRA_BUTTON:
|
||||
conf->button.with_extra = true;
|
||||
break;
|
||||
case EXTRA_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_EXTRA,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case EXTRA_LABEL:
|
||||
conf->button.extra_label = optarg;
|
||||
break;
|
||||
case HELP_BUTTON:
|
||||
conf->button.with_help = true;
|
||||
break;
|
||||
case HELP_EXIT_CODE:
|
||||
i = (int)strtol(optarg, NULL, 10);
|
||||
set_exit_code(BSDDIALOG_HELP, i);
|
||||
/* _TEM_HELP follows _HELP */
|
||||
set_exit_code(BSDDIALOG_ITEM_HELP, i);
|
||||
break;
|
||||
case HELP_LABEL:
|
||||
conf->button.help_label = optarg;
|
||||
break;
|
||||
case HELP_PRINT_ITEMS:
|
||||
opt->help_print_items = true;
|
||||
break;
|
||||
case HELP_PRINT_NAME:
|
||||
opt->help_print_item_name = true;
|
||||
break;
|
||||
case HFILE:
|
||||
conf->key.f1_file = optarg;
|
||||
break;
|
||||
case HLINE:
|
||||
if (optarg[0] != '\0')
|
||||
conf->bottomtitle = optarg;
|
||||
break;
|
||||
case HMSG:
|
||||
conf->key.f1_message = optarg;
|
||||
break;
|
||||
case IGNORE:
|
||||
opt->ignore = true;
|
||||
break;
|
||||
case INSECURE:
|
||||
conf->form.securech = '*';
|
||||
break;
|
||||
case ITEM_BOTTOM_DESC:
|
||||
opt->item_bottomdesc = true;
|
||||
break;
|
||||
case ITEM_DEPTH:
|
||||
opt->item_depth = true;
|
||||
break;
|
||||
case ITEM_PREFIX:
|
||||
opt->item_prefix = true;
|
||||
break;
|
||||
case LEFT1_BUTTON:
|
||||
conf->button.left1_label = optarg;
|
||||
break;
|
||||
case LEFT1_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_LEFT1,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case LEFT2_BUTTON:
|
||||
conf->button.left2_label = optarg;
|
||||
break;
|
||||
case LEFT2_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_LEFT2,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case LEFT3_BUTTON:
|
||||
conf->button.left3_label = optarg;
|
||||
break;
|
||||
case LEFT3_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_LEFT3,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case LOAD_THEME:
|
||||
opt->loadthemefile = optarg;
|
||||
break;
|
||||
case MAX_INPUT:
|
||||
opt->max_input_form = (u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case NO_CANCEL:
|
||||
conf->button.without_cancel = true;
|
||||
break;
|
||||
case NO_DESCRIPTIONS:
|
||||
conf->menu.no_desc = true;
|
||||
break;
|
||||
case NO_LINES:
|
||||
conf->no_lines = true;
|
||||
break;
|
||||
case NO_NAMES:
|
||||
conf->menu.no_name = true;
|
||||
break;
|
||||
case NO_OK:
|
||||
conf->button.without_ok = true;
|
||||
break;
|
||||
case NO_SHADOW:
|
||||
conf->shadow = false;
|
||||
break;
|
||||
case NORMAL_SCREEN:
|
||||
opt->screen_mode = "rmcup";
|
||||
break;
|
||||
case OK_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_OK,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case OK_LABEL:
|
||||
conf->button.ok_label = optarg;
|
||||
break;
|
||||
case OUTPUT_FD:
|
||||
opt->output_fd = (int)strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case OUTPUT_SEPARATOR:
|
||||
opt->item_output_sep = optarg;
|
||||
break;
|
||||
case QUOTED:
|
||||
opt->item_always_quote = true;
|
||||
break;
|
||||
case PRINT_MAXSIZE:
|
||||
opt->mandatory_dialog = false;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
|
||||
dprintf(opt->output_fd, "MaxSize: %d, %d\n",
|
||||
ws.ws_row, ws.ws_col);
|
||||
break;
|
||||
case PRINT_SIZE:
|
||||
conf->get_height = &opt->getH;
|
||||
conf->get_width = &opt->getW;
|
||||
break;
|
||||
case PRINT_VERSION:
|
||||
opt->mandatory_dialog = false;
|
||||
dprintf(opt->output_fd, "Version: %s\n",
|
||||
LIBBSDDIALOG_VERSION);
|
||||
break;
|
||||
case RIGHT1_BUTTON:
|
||||
conf->button.right1_label = optarg;
|
||||
break;
|
||||
case RIGHT1_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_RIGHT1,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case RIGHT2_BUTTON:
|
||||
conf->button.right2_label = optarg;
|
||||
break;
|
||||
case RIGHT2_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_RIGHT2,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case RIGHT3_BUTTON:
|
||||
conf->button.right3_label = optarg;
|
||||
break;
|
||||
case RIGHT3_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_RIGHT3,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case SAVE_THEME:
|
||||
opt->mandatory_dialog = false;
|
||||
opt->savethemefile = optarg;
|
||||
break;
|
||||
case SEPARATE_OUTPUT:
|
||||
opt->item_output_sepnl = true;
|
||||
break;
|
||||
case SHADOW:
|
||||
conf->shadow = true;
|
||||
break;
|
||||
case SINGLE_QUOTED:
|
||||
opt->item_singlequote = true;
|
||||
break;
|
||||
case SLEEP:
|
||||
conf->sleep = (u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case STDERR:
|
||||
opt->output_fd = STDERR_FILENO;
|
||||
break;
|
||||
case STDOUT:
|
||||
opt->output_fd = STDOUT_FILENO;
|
||||
break;
|
||||
case SWITCH_BUTTONS:
|
||||
conf->button.always_active = false;
|
||||
break;
|
||||
case TAB_ESCAPE:
|
||||
opt->tab_escape = true;
|
||||
break;
|
||||
case TAB_LEN:
|
||||
conf->text.tablen = (u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case TEXT_ESCAPE:
|
||||
conf->text.escape = true;
|
||||
break;
|
||||
case TEXT_UNCHANGED:
|
||||
opt->text_unchanged = true;
|
||||
break;
|
||||
case THEME:
|
||||
if (strcasecmp(optarg, "blackwhite") == 0)
|
||||
opt->theme = BSDDIALOG_THEME_BLACKWHITE;
|
||||
else if (strcasecmp(optarg, "flat") == 0)
|
||||
opt->theme = BSDDIALOG_THEME_FLAT;
|
||||
else if (strcasecmp(optarg, "3d") == 0)
|
||||
opt->theme = BSDDIALOG_THEME_3D;
|
||||
else
|
||||
exit_error(true,
|
||||
"--theme: \"%s\" is unknown", optarg);
|
||||
break;
|
||||
case TIMEOUT_EXIT_CODE:
|
||||
set_exit_code(BSDDIALOG_TIMEOUT,
|
||||
(int)strtol(optarg, NULL, 10));
|
||||
break;
|
||||
case TIME_FORMAT:
|
||||
opt->time_fmt = optarg;
|
||||
break;
|
||||
case TITLE:
|
||||
conf->title = optarg;
|
||||
break;
|
||||
/* Dialogs */
|
||||
case CALENDAR:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --calendar without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--calendar";
|
||||
opt->dialogbuilder = calendar_builder;
|
||||
break;
|
||||
case CHECKLIST:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --checklist without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--checklist";
|
||||
opt->dialogbuilder = checklist_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case DATEBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --datebox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--datebox";
|
||||
opt->dialogbuilder = datebox_builder;
|
||||
break;
|
||||
case FORM:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --form without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--form";
|
||||
opt->dialogbuilder = form_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case GAUGE:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --gauge without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--gauge";
|
||||
opt->dialogbuilder = gauge_builder;
|
||||
break;
|
||||
case INFOBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --infobox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--infobox";
|
||||
opt->dialogbuilder = infobox_builder;
|
||||
break;
|
||||
case INPUTBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --inputbox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--inputbox";
|
||||
opt->dialogbuilder = inputbox_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case MENU:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --menu without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--menu";
|
||||
opt->dialogbuilder = menu_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case MIXEDFORM:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --mixedform without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--mixedform";
|
||||
opt->dialogbuilder = mixedform_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case MIXEDGAUGE:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --mixedgauge without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--mixedgauge";
|
||||
opt->dialogbuilder = mixedgauge_builder;
|
||||
break;
|
||||
case MSGBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --msgbox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--";
|
||||
opt->dialogbuilder = msgbox_builder;
|
||||
break;
|
||||
case PAUSE:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --pause without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--pause";
|
||||
opt->dialogbuilder = pause_builder;
|
||||
break;
|
||||
case PASSWORDBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --passwordbox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--passwordbox";
|
||||
opt->dialogbuilder = passwordbox_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case PASSWORDFORM:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --passwordform "
|
||||
"without --and-dialog", opt->name);
|
||||
opt->name = "--passwordform";
|
||||
opt->dialogbuilder = passwordform_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case RADIOLIST:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --radiolist without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--radiolist";
|
||||
opt->dialogbuilder = radiolist_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case RANGEBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --rangebox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--rangebox";
|
||||
opt->dialogbuilder = rangebox_builder;
|
||||
break;
|
||||
case TEXTBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --textbox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--textbox";
|
||||
opt->dialogbuilder = textbox_builder;
|
||||
break;
|
||||
case TIMEBOX:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --timebox without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--timebox";
|
||||
opt->dialogbuilder = timebox_builder;
|
||||
break;
|
||||
case TREEVIEW:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --treeview without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--treeview";
|
||||
opt->dialogbuilder = treeview_builder;
|
||||
conf->auto_downmargin = 1;
|
||||
break;
|
||||
case YESNO:
|
||||
if (opt->dialogbuilder != NULL)
|
||||
exit_error(true, "%s and --yesno without "
|
||||
"--and-dialog", opt->name);
|
||||
opt->name = "--yesno";
|
||||
opt->dialogbuilder = yesno_builder;
|
||||
break;
|
||||
default: /* Error */
|
||||
if (opt->ignore == true)
|
||||
break;
|
||||
exit_error(true, "--ignore to continue");
|
||||
}
|
||||
}
|
||||
|
||||
return (parsed);
|
||||
}
|
451
contrib/bsddialog/utility/util_theme.c
Normal file
451
contrib/bsddialog/utility/util_theme.c
Normal file
@ -0,0 +1,451 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2022-2023 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/time.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static struct bsddialog_theme t;
|
||||
static char title[1024];
|
||||
|
||||
#define NPROPERTY 41
|
||||
#define NCOLOR 8
|
||||
#define NATTR 6
|
||||
|
||||
#define PROP_ERROR(name, error) do { \
|
||||
fclose(fp); \
|
||||
exit_error(false, "%s for \"%s\"", error, name); \
|
||||
} while (0)
|
||||
|
||||
enum typeproperty {
|
||||
BOOL,
|
||||
CHAR,
|
||||
INT,
|
||||
UINT,
|
||||
COLOR,
|
||||
COMPAT
|
||||
};
|
||||
|
||||
struct property {
|
||||
const char *comment;
|
||||
const char *name;
|
||||
enum typeproperty type;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct namevalue {
|
||||
const char *name;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
static struct namevalue color[NCOLOR] = {
|
||||
{"black", BSDDIALOG_BLACK},
|
||||
{"red", BSDDIALOG_RED},
|
||||
{"green", BSDDIALOG_GREEN},
|
||||
{"yellow", BSDDIALOG_YELLOW},
|
||||
{"blue", BSDDIALOG_BLUE},
|
||||
{"magenta", BSDDIALOG_MAGENTA},
|
||||
{"cyan", BSDDIALOG_CYAN},
|
||||
{"white", BSDDIALOG_WHITE}
|
||||
};
|
||||
|
||||
static struct namevalue attr[NATTR] = {
|
||||
{"bold", BSDDIALOG_BOLD},
|
||||
{"reverse", BSDDIALOG_REVERSE},
|
||||
{"underline", BSDDIALOG_UNDERLINE},
|
||||
{"blink", BSDDIALOG_BLINK},
|
||||
{"halfbright", BSDDIALOG_HALFBRIGHT},
|
||||
{"highlight", BSDDIALOG_HIGHLIGHT}
|
||||
};
|
||||
|
||||
static struct property p[NPROPERTY] = {
|
||||
{"\n#Terminal\n", "theme.screen.color", COLOR, &t.screen.color},
|
||||
|
||||
{"\n# Shadow\n",
|
||||
"theme.shadow.color", COLOR, &t.shadow.color},
|
||||
{"# shift down right from main widget\n",
|
||||
"theme.shadow.y", UINT, &t.shadow.y},
|
||||
{"", "theme.shadow.x", UINT, &t.shadow.x},
|
||||
|
||||
{"\n# Main widget\n",
|
||||
"theme.dialog.color", COLOR, &t.dialog.color},
|
||||
{"", "theme.dialog.delimtitle", BOOL, &t.dialog.delimtitle},
|
||||
{"", "theme.dialog.titlecolor", COLOR, &t.dialog.titlecolor},
|
||||
{"", "theme.dialog.lineraisecolor", COLOR, &t.dialog.lineraisecolor},
|
||||
{"", "theme.dialog.linelowercolor", COLOR, &t.dialog.linelowercolor},
|
||||
{"", "theme.dialog.bottomtitlecolor", COLOR,
|
||||
&t.dialog.bottomtitlecolor},
|
||||
{"", "theme.dialog.arrowcolor", COLOR, &t.dialog.arrowcolor},
|
||||
|
||||
{"\n# Menus: --checklist, --menu, --radiolist\n"
|
||||
"# prefix [selector] shortcut name desc bottomdesc\n",
|
||||
"theme.menu.f_prefixcolor", COLOR, &t.menu.f_prefixcolor},
|
||||
{"", "theme.menu.prefixcolor", COLOR, &t.menu.prefixcolor},
|
||||
{"", "theme.menu.f_selectorcolor", COLOR, &t.menu.f_selectorcolor},
|
||||
{"", "theme.menu.selectorcolor", COLOR, &t.menu.selectorcolor},
|
||||
{"", "theme.menu.f_namecolor", COLOR, &t.menu.f_namecolor},
|
||||
{"", "theme.menu.namecolor", COLOR, &t.menu.namecolor},
|
||||
{"", "theme.menu.f_desccolor", COLOR, &t.menu.f_desccolor},
|
||||
{"", "theme.menu.desccolor", COLOR, &t.menu.desccolor},
|
||||
{"", "theme.menu.f_shortcutcolor", COLOR, &t.menu.f_shortcutcolor},
|
||||
{"", "theme.menu.shortcutcolor", COLOR, &t.menu.shortcutcolor},
|
||||
{"", "theme.menu.bottomdesccolor", COLOR, &t.menu.bottomdesccolor},
|
||||
{"# bsddialog_menutype BSDDIALOG_SEPARATOR\n",
|
||||
"theme.menu.sepnamecolor", COLOR, &t.menu.sepnamecolor},
|
||||
{"", "theme.menu.sepdesccolor", COLOR, &t.menu.sepdesccolor},
|
||||
|
||||
{"\n# Forms\n",
|
||||
"theme.form.f_fieldcolor", COLOR, &t.form.f_fieldcolor},
|
||||
{"", "theme.form.fieldcolor", COLOR, &t.form.fieldcolor},
|
||||
{"", "theme.form.readonlycolor", COLOR, &t.form.readonlycolor},
|
||||
{"", "theme.form.bottomdesccolor", COLOR, &t.form.bottomdesccolor},
|
||||
|
||||
{"\n# Bar of --gauge, --mixedgauge, --pause, --rangebox\n",
|
||||
"theme.bar.f_color", COLOR, &t.bar.f_color},
|
||||
{"", "theme.bar.color", COLOR, &t.bar.color},
|
||||
|
||||
{"\n# Buttons\n",
|
||||
"theme.button.minmargin", UINT, &t.button.minmargin},
|
||||
{"", "theme.button.maxmargin", UINT, &t.button.maxmargin},
|
||||
{"", "theme.button.leftdelim", CHAR, &t.button.leftdelim},
|
||||
{"", "theme.button.rightdelim", CHAR, &t.button.rightdelim},
|
||||
{"", "theme.button.f_delimcolor", COLOR, &t.button.f_delimcolor},
|
||||
{"", "theme.button.delimcolor", COLOR, &t.button.delimcolor},
|
||||
{"", "theme.button.f_color", COLOR, &t.button.f_color},
|
||||
{"", "theme.button.color", COLOR, &t.button.color},
|
||||
{"", "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor},
|
||||
{"", "theme.button.shortcutcolor", COLOR, &t.button.shortcutcolor},
|
||||
|
||||
{"\n#Compatibility. Do not use, can be deleted\n",
|
||||
"use_shadow", COMPAT, NULL}
|
||||
};
|
||||
|
||||
void savetheme(const char *file)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int flags;
|
||||
enum bsddialog_color bg, fg;
|
||||
time_t clock;
|
||||
FILE *fp;
|
||||
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
exit_error(false,
|
||||
"cannot save theme: %s", bsddialog_geterror());
|
||||
|
||||
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);
|
||||
|
||||
fprintf(fp, "### bsddialog theme - %s\n", ctime(&clock));
|
||||
|
||||
fputs("# Colors: ", fp);
|
||||
fputs("black red green yellow blue magenta cyan white.\n", fp);
|
||||
fputs("# Attributes: ", fp);
|
||||
fputs("bold reverse underline blink halfbright highlight.\n", fp);
|
||||
fputs("# f_* refers to focus for an element with selected or ", fp);
|
||||
fputs("unselected state.\n\n", fp);
|
||||
|
||||
fprintf(fp, "version %s\n", LIBBSDDIALOG_VERSION);
|
||||
|
||||
for (i = 0; i < NPROPERTY; i++) {
|
||||
if (p[i].type == COMPAT)
|
||||
continue;
|
||||
fprintf(fp, "%s%s", p[i].comment, p[i].name);
|
||||
switch (p[i].type) {
|
||||
case CHAR:
|
||||
fprintf(fp, " %c\n", *((char*)p[i].value));
|
||||
break;
|
||||
case INT:
|
||||
fprintf(fp, " %d\n", *((int*)p[i].value));
|
||||
break;
|
||||
case UINT:
|
||||
fprintf(fp, " %u\n", *((unsigned int*)p[i].value));
|
||||
break;
|
||||
case BOOL:
|
||||
fprintf(fp, " %s\n",
|
||||
*((bool*)p[i].value) ? "true" : "false");
|
||||
break;
|
||||
case COLOR:
|
||||
bsddialog_color_attrs(*(int*)p[i].value, &fg, &bg,
|
||||
&flags);
|
||||
fprintf(fp, " %s %s", color[fg].name, color[bg].name);
|
||||
for (j = 0; j < NATTR; j++)
|
||||
if (flags & attr[j].value)
|
||||
fprintf(fp, " %s", attr[j].name);
|
||||
fputs("\n", fp);
|
||||
break;
|
||||
case COMPAT:
|
||||
/* Do not save compat property for now */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void loadtheme(const char *file, bool compatibility)
|
||||
{
|
||||
bool boolvalue;
|
||||
char charvalue, *value;
|
||||
char line[BUFSIZ], name[BUFSIZ], c1[BUFSIZ], c2[BUFSIZ];
|
||||
int i, j, intvalue;
|
||||
unsigned int uintvalue, flags;
|
||||
enum bsddialog_color bg, fg;
|
||||
FILE *fp;
|
||||
|
||||
if (bsddialog_hascolors() == false)
|
||||
return;
|
||||
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
exit_error(false, "Cannot get current theme: %s",
|
||||
bsddialog_geterror());
|
||||
|
||||
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')
|
||||
continue; /* superfluous, only for efficiency */
|
||||
sscanf(line, "%s", name);
|
||||
value = NULL; /* useless init, fix compiler warning */
|
||||
for (i = 0; i < NPROPERTY; i++) {
|
||||
if (strcmp(name, p[i].name) == 0) {
|
||||
value = &line[strlen(name)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= NPROPERTY) {
|
||||
/* unknown name in property p[] */
|
||||
if (strcmp(name, "version") == 0)
|
||||
continue; /* nothing for now */
|
||||
else if (compatibility)
|
||||
continue; /* just ignore */
|
||||
else
|
||||
PROP_ERROR(name, "Unknown theme property name");
|
||||
}
|
||||
switch (p[i].type) {
|
||||
case CHAR:
|
||||
while (value[0] == ' ' || value[0] == '\n' ||
|
||||
value[0] == '\0')
|
||||
value++;
|
||||
if (sscanf(value, "%c", &charvalue) != 1)
|
||||
PROP_ERROR(p[i].name, "Cannot get a char");
|
||||
*((int*)p[i].value) = charvalue;
|
||||
break;
|
||||
case INT:
|
||||
if (sscanf(value, "%d", &intvalue) != 1)
|
||||
PROP_ERROR(p[i].name, "Cannot get a int");
|
||||
*((int*)p[i].value) = intvalue;
|
||||
break;
|
||||
case UINT:
|
||||
if (sscanf(value, "%u", &uintvalue) != 1)
|
||||
PROP_ERROR(p[i].name, "Cannot get a uint");
|
||||
*((unsigned int*)p[i].value) = uintvalue;
|
||||
break;
|
||||
case BOOL:
|
||||
boolvalue = (strstr(value, "true") != NULL) ?
|
||||
true :false;
|
||||
*((bool*)p[i].value) = boolvalue;
|
||||
break;
|
||||
case COLOR:
|
||||
if (sscanf(value, "%s %s", c1, c2) != 2)
|
||||
PROP_ERROR(p[i].name, "Cannot get 2 colors");
|
||||
/* Foreground */
|
||||
for (j = 0; j < NCOLOR ; j++)
|
||||
if ((strstr(c1, color[j].name)) != NULL)
|
||||
break;
|
||||
if (j >= NCOLOR)
|
||||
PROP_ERROR(p[i].name, "Bad foreground");
|
||||
fg = color[j].value;
|
||||
/* Background */
|
||||
for (j = 0; j < NCOLOR ; j++)
|
||||
if ((strstr(c2, color[j].name)) != NULL)
|
||||
break;
|
||||
if (j >= NCOLOR)
|
||||
PROP_ERROR(p[i].name, "Bad background");
|
||||
bg = color[j].value;
|
||||
/* Flags */
|
||||
flags = 0;
|
||||
for (j = 0; j < NATTR; j++)
|
||||
if (strstr(value, attr[j].name) != NULL)
|
||||
flags |= attr[j].value;
|
||||
*((int*)p[i].value) = bsddialog_color(fg, bg, flags);
|
||||
break;
|
||||
case COMPAT:
|
||||
/*
|
||||
* usr.sbin/bsdconfig/share/dialog.subr:2255
|
||||
* uses this parameter to set NO_SHADOW.
|
||||
* Set t.shadow.[y|x] for compatibilty.
|
||||
*/
|
||||
if (strcmp(name, "use_shadow") == 0) {
|
||||
if (strcasestr(value, "off") != NULL)
|
||||
t.shadow.y = t.shadow.x = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(bsddialog_set_theme(&t) != BSDDIALOG_OK)
|
||||
exit_error(false, bsddialog_geterror());
|
||||
}
|
||||
|
||||
void setdeftheme(enum bsddialog_default_theme theme)
|
||||
{
|
||||
if (bsddialog_hascolors() == false)
|
||||
return;
|
||||
if (bsddialog_set_default_theme(theme) != BSDDIALOG_OK)
|
||||
exit_error(false, bsddialog_geterror());
|
||||
}
|
||||
|
||||
void startuptheme(void)
|
||||
{
|
||||
bool sep;
|
||||
char *env, *file, *home, path[PATH_MAX];
|
||||
|
||||
env = getenv("NO_COLOR");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
setdeftheme(BSDDIALOG_THEME_BLACKWHITE);
|
||||
|
||||
if ((home = getenv("HOME")) != NULL) {
|
||||
sep = (strcmp(home, "/") == 0) ? false : true;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s%s.bsddialog.conf",
|
||||
home, sep ? "/" : "");
|
||||
if (access(path, F_OK) == 0)
|
||||
loadtheme(path, false);
|
||||
|
||||
if ((file = getenv("BSDDIALOG_COMPATRC")) != NULL) {
|
||||
snprintf(path, PATH_MAX, "%s%s%s",
|
||||
home, sep ? "/" : "", file);
|
||||
if (access(path, F_OK) == 0)
|
||||
loadtheme(path, true);
|
||||
}
|
||||
}
|
||||
if ((file = getenv("BSDDIALOG_THEMEFILE")) != NULL) {
|
||||
if (access(file, F_OK) == 0)
|
||||
loadtheme(file, false);
|
||||
}
|
||||
}
|
||||
|
||||
void bikeshed(struct bsddialog_conf *conf)
|
||||
{
|
||||
int margin, i;
|
||||
int colors[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
char delim[8] = {'[', '<', '(', '|', ']', '>', ')', '|'};
|
||||
enum bsddialog_color col[6];
|
||||
struct timeval tv;
|
||||
|
||||
/* theme */
|
||||
if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
|
||||
exit_error(false, bsddialog_geterror());
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
srand(tv.tv_usec);
|
||||
for (i = 0; i < 6; i++) {
|
||||
do {
|
||||
col[i] = rand() % 8;
|
||||
} while (colors[col[i]] == 1);
|
||||
colors[col[i]] = 1;
|
||||
}
|
||||
|
||||
t.screen.color = bsddialog_color(col[4], col[3], 0);
|
||||
|
||||
t.shadow.color = bsddialog_color(col[0], col[0], 0);
|
||||
t.shadow.y = 1,
|
||||
t.shadow.x = 2,
|
||||
|
||||
t.dialog.delimtitle = (~rand() & 1) ? true : false;
|
||||
t.dialog.titlecolor = bsddialog_color(col[3], col[5], 0);
|
||||
t.dialog.lineraisecolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.linelowercolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.color = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.bottomtitlecolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.dialog.arrowcolor = bsddialog_color(col[3], col[5], 0);
|
||||
|
||||
t.menu.f_prefixcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.prefixcolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.menu.f_selectorcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.selectorcolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.menu.f_desccolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.desccolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.menu.f_namecolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.menu.namecolor = bsddialog_color(col[3], col[5], 0);
|
||||
t.menu.f_shortcutcolor = bsddialog_color(col[1], col[3], 0);
|
||||
t.menu.shortcutcolor = bsddialog_color(col[1], col[5], 0);
|
||||
t.menu.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
|
||||
t.menu.sepnamecolor = bsddialog_color(col[1], col[5], 0);
|
||||
t.menu.sepdesccolor = bsddialog_color(col[1], col[5], 0);
|
||||
|
||||
t.form.f_fieldcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.form.fieldcolor = bsddialog_color(col[5], col[4], 0);
|
||||
t.form.readonlycolor = bsddialog_color(col[4], col[5], 0);
|
||||
t.form.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
|
||||
|
||||
t.bar.f_color = bsddialog_color(col[5], col[3], 0);
|
||||
t.bar.color = bsddialog_color(col[3], col[5], 0);
|
||||
|
||||
t.button.minmargin = 1,
|
||||
t.button.maxmargin = 5,
|
||||
i = rand() % 4;
|
||||
t.button.leftdelim = delim[i];
|
||||
t.button.rightdelim = delim[i + 4];
|
||||
t.button.f_delimcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.button.delimcolor = bsddialog_color(col[0], col[5], 0);
|
||||
t.button.f_color = bsddialog_color(col[2], col[3], 0);
|
||||
t.button.color = bsddialog_color(col[0], col[5], 0);
|
||||
t.button.f_shortcutcolor = bsddialog_color(col[5], col[3], 0);
|
||||
t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0);
|
||||
|
||||
if (bsddialog_set_theme(&t))
|
||||
exit_error(false, bsddialog_geterror());
|
||||
|
||||
/* conf */
|
||||
conf->button.always_active = (~rand() & 1) ? true : false;
|
||||
if ((i = rand() % 3) != 0) /* default "d/m/y" */
|
||||
conf->date.format = (i & 1) ? "m/d/y" : "y/m/d" ;
|
||||
if (conf->title != NULL) {
|
||||
memset(title, 0, 1024);
|
||||
margin = rand() % 5;
|
||||
memset(title, ' ', margin);
|
||||
strcpy(title + margin, conf->title);
|
||||
memset(title + strlen(title), ' ', margin);
|
||||
conf->title = title;
|
||||
}
|
||||
}
|
@ -6,9 +6,8 @@ LIB= bsddialog
|
||||
PRIVATELIB= yes
|
||||
SHLIB_MAJOR= 0
|
||||
SRCS= barbox.c \
|
||||
calendarbox.c \
|
||||
datebox.c \
|
||||
formbox.c \
|
||||
infobox.c \
|
||||
lib_util.c \
|
||||
lib_util.h \
|
||||
libbsddialog.c \
|
||||
|
@ -1,10 +1,13 @@
|
||||
BSDDIALOG= ${SRCTOP}/contrib/bsddialog
|
||||
BSDDIALOG= ${SRCTOP}/contrib/bsddialog/utility
|
||||
.PATH: ${BSDDIALOG}
|
||||
|
||||
PROG= bsddialog
|
||||
SRCS= bsddialog.c util_theme.c
|
||||
SRCS= bsddialog.c \
|
||||
util_builders.c \
|
||||
util_cli.c \
|
||||
util_theme.c
|
||||
MAN= bsddialog.1
|
||||
CFLAGS+= -I${BSDDIALOG}/lib
|
||||
CFLAGS+= -I${BSDDIALOG}/../lib
|
||||
LIBADD= bsddialog tinfow
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -62,7 +62,7 @@ diskmenu_show(const char *title, const char *text, struct partedit_item *items,
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = title;
|
||||
conf.menu.align_left = true;
|
||||
conf.text.highlight = true;
|
||||
conf.text.escape = true;
|
||||
conf.key.f1_message="[\\Z1\\ZbC\\Znreate]: a new partition.\n"
|
||||
"[\\Z1\\ZbD\\Znelete]: selected partition(s).\n"
|
||||
"[\\Z1\\ZbC\\Znhange]: partition type or mountpoint.\n"
|
||||
@ -76,8 +76,8 @@ diskmenu_show(const char *title, const char *text, struct partedit_item *items,
|
||||
conf.button.cancel_label = "Modify";
|
||||
conf.button.with_help = true;
|
||||
conf.button.help_label = "Revert";
|
||||
conf.button.generic1_label = "Auto";
|
||||
conf.button.generic2_label = "Finish";
|
||||
conf.button.right1_label = "Auto";
|
||||
conf.button.right2_label = "Finish";
|
||||
conf.button.default_label = "Finish";
|
||||
output = bsddialog_menu(&conf, text, 20, 0, 10, nitems, bsditems,
|
||||
focusitem);
|
||||
|
@ -33,8 +33,8 @@
|
||||
#define BUTTON_DELETE BSDDIALOG_EXTRA
|
||||
#define BUTTON_MODIFY BSDDIALOG_CANCEL
|
||||
#define BUTTON_REVERT BSDDIALOG_HELP
|
||||
#define BUTTON_AUTO BSDDIALOG_GENERIC1
|
||||
#define BUTTON_FINISH BSDDIALOG_GENERIC2
|
||||
#define BUTTON_AUTO BSDDIALOG_RIGHT1
|
||||
#define BUTTON_FINISH BSDDIALOG_RIGHT2
|
||||
|
||||
struct partedit_item {
|
||||
int indentation;
|
||||
|
@ -639,9 +639,8 @@ gpart_edit(struct gprovider *pp)
|
||||
items[1].init = sizestr;
|
||||
|
||||
editpart:
|
||||
conf.form.value_without_ok = true;
|
||||
conf.title = "Edit Partition";
|
||||
choice = bsddialog_form(&conf, "", 0, 0, 0, nitems, items);
|
||||
choice = bsddialog_form(&conf, "", 0, 0, 0, nitems, items, NULL);
|
||||
|
||||
if (choice == BSDDIALOG_CANCEL)
|
||||
goto endedit;
|
||||
@ -1129,12 +1128,10 @@ addpartform:
|
||||
if (interactive) {
|
||||
conf.button.with_extra = true;
|
||||
conf.button.extra_label = "Options";
|
||||
conf.form.value_without_ok = true;
|
||||
conf.title = "Add Partition";
|
||||
choice = bsddialog_form(&conf, "", 0, 0, 0, nitems, items);
|
||||
choice = bsddialog_form(&conf, "", 0, 0, 0, nitems, items, NULL);
|
||||
conf.button.with_extra = false;
|
||||
conf.button.extra_label = NULL;
|
||||
conf.form.value_without_ok = false;
|
||||
switch (choice) {
|
||||
case BSDDIALOG_OK:
|
||||
break;
|
||||
|
@ -73,7 +73,7 @@ startwizard:
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_clearterminal();
|
||||
bsddialog_clear(0);
|
||||
bsddialog_backtitle(&conf, "FreeBSD Installer");
|
||||
schemeroot = wizard_partition(&mesh, disk);
|
||||
free(disk);
|
||||
@ -81,7 +81,7 @@ startwizard:
|
||||
if (schemeroot == NULL)
|
||||
return (1);
|
||||
|
||||
bsddialog_clearterminal();
|
||||
bsddialog_clear(0);
|
||||
bsddialog_backtitle(&conf, "FreeBSD Installer");
|
||||
error = geom_gettree(&mesh);
|
||||
if (error != 0) {
|
||||
|
@ -123,7 +123,7 @@ main(int argc, const char **argv)
|
||||
|
||||
/* Show the part editor either immediately, or to confirm wizard */
|
||||
while (prompt != NULL) {
|
||||
bsddialog_clearterminal();
|
||||
bsddialog_clear(0);
|
||||
if (!sade_mode)
|
||||
bsddialog_backtitle(&conf, "FreeBSD Installer");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user