contrib/bsddialog: Import version 0.3
New features overview: * Unicode. User interface handles multi-column characters. API can handle char* like a multibyte character string. Internally wide characters are used for keyboard input, to adapt word wrapping and dynamic text auto-sizing for multi-column characters. * Forms refactoring. Complete rewrite deleting libformw dependency. * Theme. New utility options to save and load custom theme at run-time. * TUI navigation. Added keys to navigate input components. Changed default focus behavior of input dialogs to be LGPL-dialog-like; a new option can set the previous whiptail-like behavior. See /usr/src/contrib/bsddialog/CHANGELOG '2022-08-29 Version 0.3' for more detailed information. Merge commit '2c9fd7655ba54e7239f528e1af9fe09662de9b03'
This commit is contained in:
commit
b319d93437
2
contrib/bsddialog/.gitignore
vendored
2
contrib/bsddialog/.gitignore
vendored
@ -7,6 +7,7 @@ examples_library/checklist
|
||||
examples_library/datebox
|
||||
examples_library/form
|
||||
examples_library/formw
|
||||
examples_library/margin
|
||||
examples_library/menu
|
||||
examples_library/mixedlist
|
||||
examples_library/radiolist
|
||||
@ -19,6 +20,7 @@ examples_library/rangebox
|
||||
examples_library/sade
|
||||
examples_library/timebox
|
||||
examples_library/yesno
|
||||
examples_library/u_msgbox
|
||||
*.gz
|
||||
lib/libbsddialog.so*
|
||||
BSDDIALOG.geany
|
||||
|
@ -1,4 +1,77 @@
|
||||
2022-03-02 version 0.2
|
||||
2022-08-29 Version 0.3
|
||||
|
||||
Utility:
|
||||
* add: --textbox accepts options for the first button.
|
||||
* add: --columns-per-row option for text autosizing.
|
||||
* add: --load-theme option to read and set a custom theme at runtime.
|
||||
* add: --save-theme option to save current theme.
|
||||
* add: --bikeshed option for random settings.
|
||||
* add: --switch-buttons enables focus switching: buttons / input
|
||||
components. 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.
|
||||
* fix: --hline with empty string.
|
||||
* fix: avoid to overlay the backtitle by setting a top margin.
|
||||
* fix: avoid to overlay down shadow with menus and forms bottomdesc
|
||||
by setting a down margin.
|
||||
* fix: --form read-only flag with multiple fields.
|
||||
|
||||
Library:
|
||||
* add: conf.auto_topmargin and conf.auto_downmargin.
|
||||
* add: bsddialog_textbox() accepts conf.button.* for the first button.
|
||||
* add: bsddialog_textbox() arrows and percentage.
|
||||
* add: conf.text.cols_per_row to set a ratio for text autosizing.
|
||||
* add: timebox and datebox arrows and focus background for boxes.
|
||||
* add: timebox and datebox UP key to switch focus.
|
||||
* add: bsddialog_init_notheme() in bsddialo_theme.h.
|
||||
* add: bsddialog_hascolors() in bsddialo_theme.h.
|
||||
* add: theme.form.bottomdesccolor and theme.menu.bottomdesccolor.
|
||||
* add: conf.button.always_active to disable buttons/input-boxes switch.
|
||||
* add: dynamic buttons margin.
|
||||
- add: theme.button.minmargin and theme.button.maxmargin.
|
||||
- delete: theme.button.hmargin.
|
||||
* add: Unicode.
|
||||
- UI handles multicolumn charachters: backtitle, title,
|
||||
text (word wrapping, autosizing), menus (shortcuts, name, desc),
|
||||
forms (label, field), textbox, mixedgauge (minilabel),
|
||||
buttons (label, shortcuts), bottomtitle.
|
||||
- API handles char* arguments like multibyte charachter string,
|
||||
depending on the current locale.
|
||||
- Internally wide charachters are used to get input from keyboard
|
||||
and to adapt word wrapping and dynamic text autosizing to
|
||||
muticolumn charachters.
|
||||
* refactoring: (rewrite) form.c.
|
||||
- delete: libformw dep implementing its features from scratch.
|
||||
- delete: maxvaluelen >= valuelen constraint.
|
||||
- delete: conf.form.enable_wchar, get always unicode (wchar) input.
|
||||
- add: KEY_HOME, KEY_END, KEY_PPAGE, KEY_NPAGE keys in field.
|
||||
- add: KEY_UP can move focus from buttons to fields.
|
||||
- add: KEY_DOWN can move focus from item to buttons, if nitem is 1.
|
||||
- add: conf.form.securembch secure multibyte charachter.
|
||||
- add: BSDDIALOG_FIELDNOCOLOR for formitem.flags.
|
||||
- add: BSDDIALOG_FIELDCURSOREND for formitem.flags.
|
||||
- add: BSDDIALOG_FIELDEXTEND for formitem.flags.
|
||||
- add: BSDDIALOG_FIELDSINGLEBYTE for formitem.flags.
|
||||
- add: resizing and refresh after KEY_RESIZE (SIGWINCH).
|
||||
- add: items scrolling.
|
||||
- add: conf.form.value_wchar, value is wchar_t* instead of MB-char*.
|
||||
- add: formheight autosizing.
|
||||
- add: dynamic item position.
|
||||
* fix: bsddialog_gauge() with fd < 0.
|
||||
* fix: internal segmentation fault with disabled shadow.
|
||||
* fix: bsddialog_gauge() refresh new text.
|
||||
* fix: center position without shadow.
|
||||
* fix: bsddialog_infobox() with zero text length.
|
||||
* fix: text wrapping with more than 1024 words.
|
||||
* fix: rename theme.shadow.h to theme.shadow.y.
|
||||
* fix: rename theme.shadow.w to theme.shadow.x.
|
||||
* fix: menurows autosize with fixed rows improving text_size().
|
||||
* fix: messagebox.c scrolling and checksize without text.
|
||||
|
||||
|
||||
2022-03-02 Version 0.2
|
||||
|
||||
Utility:
|
||||
* add: (this) CHANGELOG.
|
||||
@ -31,7 +104,7 @@
|
||||
* improve: "menus" colors for accessibility.
|
||||
|
||||
|
||||
2022-01-27 version 0.1
|
||||
2022-01-27 Version 0.1
|
||||
|
||||
* Common-Options: --ascii-lines, --backtitle <backtitle>, --begin-x <x>,
|
||||
--begin-y <y>, --cancel-label <label>, --clear, --colors, --cr-wrap,
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT= bsddialog
|
||||
SOURCES= bsddialog.c
|
||||
SOURCES= bsddialog.c util_theme.c
|
||||
OBJECTS= $(SOURCES:.c=.o)
|
||||
LIBPATH= ./lib
|
||||
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
OUTPUT= bsddialog
|
||||
SOURCES= bsddialog.c
|
||||
SOURCES= bsddialog.c util_theme.c
|
||||
OBJECTS= ${SOURCES:.c=.o}
|
||||
LIBPATH= ${.CURDIR}/lib
|
||||
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
|
||||
|
@ -1,14 +1,13 @@
|
||||
# BSDDialog 0.2
|
||||
# BSDDialog 0.3
|
||||
|
||||
|
||||
This project provides **bsddialog** and **libbsddialog**, an utility and a
|
||||
library to build scripts and tools with TUI dialogs and widgets.
|
||||
This project provides **bsddialog** and **libbsddialog**, an utility
|
||||
and a library to build scripts and tools with TUI dialogs and widgets.
|
||||
|
||||
|
||||
## Intro
|
||||
|
||||
Briefly:
|
||||
<https://www.freebsd.org/status/report-2021-04-2021-06/#_bsddialog_tui_widgets>
|
||||
<https://www.freebsd.org/status/report-2021-04-2021-06/bsddialog/>
|
||||
|
||||
Utility:
|
||||
<https://alfonsosiciliano.gitlab.io/posts/2021-12-07-bsddialog.html>
|
||||
@ -31,6 +30,15 @@ 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)
|
||||
@ -101,6 +109,7 @@ in the _Public Domain_ to build new projects:
|
||||
```
|
||||
% cd examples_library
|
||||
% sh compile
|
||||
% ./checklist
|
||||
% ./datebox
|
||||
% ./form
|
||||
% ./infobox
|
||||
@ -114,4 +123,10 @@ in the _Public Domain_ to build new projects:
|
||||
% ./timebox
|
||||
% ./yesno
|
||||
```
|
||||
|
||||
|
||||
## TODO and Ideas
|
||||
|
||||
- menubar feature
|
||||
- key callback
|
||||
- Right-To-Left text
|
||||
|
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 3, 2022
|
||||
.Dd August 29, 2022
|
||||
.Dt BSDDIALOG 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -74,6 +74,13 @@ Title on the top side of the screen.
|
||||
Dialog horizontal position, 0 is the left screen side, -1 center.
|
||||
.It Fl Fl begin-y Ar y
|
||||
Dialog vertical position, 0 is the top screen side, -1 center.
|
||||
.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
|
||||
.Fl Fl switch-buttons .
|
||||
Zero padding with time or date output.
|
||||
.It Fl Fl cancel-label Ar label
|
||||
Label for the
|
||||
.Dq Cancel
|
||||
@ -100,7 +107,7 @@ cyan.
|
||||
.It Dq \eZ7
|
||||
white.
|
||||
.It Dq \eZr
|
||||
reverse foreground and background colors.
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZb
|
||||
@ -112,8 +119,11 @@ underline.
|
||||
.It Dq \eZU
|
||||
disable underline.
|
||||
.It Dq \eZn
|
||||
restore to normal text.
|
||||
restore normal text.
|
||||
.El
|
||||
.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 .
|
||||
.It Fl Fl cr-wrap
|
||||
Replace new line with a space in
|
||||
.Ar text .
|
||||
@ -141,7 +151,7 @@ Equivalent to
|
||||
.Fl Fl default-no .
|
||||
.It Fl Fl disable-esc
|
||||
Disable ESC key to quit.
|
||||
.It Fl Fl esc-cancelvalue
|
||||
.It Fl Fl esc-return-cancel
|
||||
Exits with the
|
||||
.Dq Cancel
|
||||
button value if the ESC key is pressed.
|
||||
@ -197,8 +207,7 @@ Do not exit with unknown options.
|
||||
.It Fl Fl insecure
|
||||
Print
|
||||
.Sq *
|
||||
to hide passwords while typing, default space
|
||||
.Sq " " .
|
||||
to hide passwords while typing; whitespace otherwise.
|
||||
.It Fl Fl item-depth
|
||||
Specify a margin for items, available for Checklist, Menu and Radiolist.
|
||||
.It Fl Fl item-help
|
||||
@ -206,9 +215,12 @@ Set a help string for each element of a Checklist, Form, Menu, Mixedform,
|
||||
Passwordform, Radiolist and Treeview to display at the bottom screen side.
|
||||
.It Fl Fl item-prefix
|
||||
Set a string to prefix each item of a Checklist, Menu, Radiolist or Treeview.
|
||||
.It Fl Fl load-theme Ar file
|
||||
Load theme from
|
||||
.Ar file .
|
||||
.It Fl Fl max-input Ar size
|
||||
Maximum length of the input for
|
||||
.Fl Fl input-box
|
||||
.Fl Fl inputbox
|
||||
ans
|
||||
.Fl Fl passwordbox ,
|
||||
default 2048.
|
||||
@ -262,6 +274,8 @@ Print Dialog height and widget at exit.
|
||||
Print version.
|
||||
.It Fl Fl quoted
|
||||
Quote items in output, default only when necessary.
|
||||
.It Fl Fl save-theme Ar file
|
||||
Save the current theme.
|
||||
.It Fl Fl separate-output
|
||||
Separate selected items with a new line and avoid to quote.
|
||||
.It Fl Fl separator Ar sep
|
||||
@ -279,6 +293,18 @@ seconds to close the dialog.
|
||||
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,
|
||||
otherwise buttons are always active and ENTER key closes the dialog.
|
||||
Suitable for:
|
||||
.Fl Fl form ,
|
||||
.Fl Fl inputbox ,
|
||||
.Fl Fl mixedform ,
|
||||
.Fl Fl passwordbox ,
|
||||
.Fl Fl passwordform ,
|
||||
.Fl Fl timebox
|
||||
and
|
||||
.Fl Fl datebox .
|
||||
.It Fl Fl tab-len Ar spaces
|
||||
Number of spaces to print a TAB in
|
||||
.Ar text .
|
||||
@ -319,7 +345,7 @@ is the graphical height of the list, 0 for autosize.
|
||||
.It Fl Fl datebox Ar text Ar rows Ar cols Op Ar year Ar month Ar day
|
||||
Dialog to select a date.
|
||||
.It Fl Fl form Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
|
||||
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxvaluelen Oc ...
|
||||
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters Oc ...
|
||||
Dialog to get a list of strings via forms.
|
||||
A form has a
|
||||
.Ar label
|
||||
@ -333,19 +359,21 @@ and
|
||||
.Ar xfield
|
||||
with graphical length
|
||||
.Ar fieldlen ,
|
||||
.Ar maxvaluelen
|
||||
.Ar maxletters
|
||||
is the maximum input length.
|
||||
The field can be customized, if
|
||||
.Ar fieldlen
|
||||
is 0 its length is the absolute value of
|
||||
.Ar maxvaluelen ,
|
||||
if
|
||||
.Ar maxvaluelen
|
||||
is negative the field is read only,
|
||||
is negative the field is read only and its absolute value is the field length.
|
||||
If
|
||||
.Ar maxletters
|
||||
is 0 it is the absolute value of
|
||||
.Ar fieldlen .
|
||||
.Ar init
|
||||
is a default value.
|
||||
.Ar formrows
|
||||
is the graphical height of the list, has to be at least the number of forms.
|
||||
is the graphical height of the list,
|
||||
.Dv 0
|
||||
for autosize.
|
||||
.It Fl Fl gauge Ar text Ar rows Ar cols Op Ar percentage
|
||||
Dialog with a bar to shows
|
||||
.Ar percentage ,
|
||||
@ -374,7 +402,7 @@ The name of the selected item is printed to standard error.
|
||||
.Ar menurows
|
||||
is the graphical height of the list, 0 for autosize.
|
||||
.It Fl Fl mixedform Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
|
||||
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxvaluelen Ar flag Oc ...
|
||||
Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters Ar flag Oc ...
|
||||
Dialog to get a list of strings via forms.
|
||||
A form has a
|
||||
.Ar label
|
||||
@ -388,7 +416,7 @@ at the position
|
||||
.Ar yfield
|
||||
and
|
||||
.Ar xfield ,
|
||||
.Ar maxvaluelen
|
||||
.Ar maxletters
|
||||
is the maximum input length,
|
||||
.Ar init
|
||||
is a default value,
|
||||
@ -396,7 +424,9 @@ is a default value,
|
||||
can be 0 for normal field, 1 to hide the typed characters and 2 to set the
|
||||
field read only.
|
||||
.Ar formrows
|
||||
is the graphical height of the list, has to be at least the number of forms.
|
||||
is the graphical height of the list,
|
||||
.Dv 0
|
||||
for autosize.
|
||||
.It Fl Fl mixedgauge Ar text Ar rows Ar cols Ar mainperc Oo Ar minilabel \
|
||||
Ar miniperc Oc ...
|
||||
Dialog to show a main bar to represent
|
||||
@ -436,7 +466,8 @@ Dialog to get a password,
|
||||
.Ar init
|
||||
is the default value.
|
||||
.It Fl Fl passwordform Ar text Ar rows Ar cols Ar formrows Oo Ar label \
|
||||
Ar ylabel Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar valuelen Oc ...
|
||||
Ar ylabel Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxletters \
|
||||
Oc ...
|
||||
Dialog to get a list of passwords, equivalent to
|
||||
.Fl Fl form
|
||||
except typed characters are hidden.
|
||||
@ -531,14 +562,39 @@ Backtitle, title and message:
|
||||
Yes-No Question and theme:
|
||||
.Dl bsddialog --theme blackwhite --yesno Question 10 30
|
||||
.Pp
|
||||
Save a custom theme:
|
||||
.Dl bsddialog --save-theme mytheme.txt --infobox \*qSaving theme...\*q 0 0
|
||||
.Pp
|
||||
Load a custom theme:
|
||||
.Dl bsddialog --load-theme mytheme.txt --infobox \*qCustom theme\*q 0 0
|
||||
.Pp
|
||||
Checklist:
|
||||
.Dl bsddialog --checklist Checklist 0 0 3 N1 \&D1 off N2 D2 on N3 D3 off
|
||||
.Pp
|
||||
Mixedgauge:
|
||||
.Dl bsddialog --sleep 3 --mixedgauge Example 10 30 60 L1 "\(dq" -1" L2 30
|
||||
.Pp
|
||||
Form:
|
||||
.Dl bsddialog --form Form 0 0 2 L1: 1 1 X 1 5 20 25 L2: 2 1 X 2 5 20 25
|
||||
.Dl bsddialog --form Form 0 0 0 L1: 0 0 X 0 4 20 25 L2: 1 0 Y 1 4 20 25
|
||||
.Pp
|
||||
Bikeshed:
|
||||
.Dl bsddialog --bikeshed --inputbox Example 0 0
|
||||
.Pp
|
||||
Mixedgauge:
|
||||
.Dl bsddialog --sleep 3 --mixedgauge Example 10 30 60 L1 \*q -1\*q L2 30
|
||||
.Pp
|
||||
Mixedgauge script:
|
||||
.Bd -literal -offset indent -compact
|
||||
perc=0
|
||||
while [ $perc -le 100 ]
|
||||
do
|
||||
bsddialog --sleep 1 --title Mixedgauge \e
|
||||
--mixedgauge "\enExample...\en" 0 0 $perc \e
|
||||
"Hidden" " -9" \e
|
||||
"Label 1" " -4" \e
|
||||
"Label 2" " -4" \e
|
||||
"Label 3" $perc
|
||||
|
||||
perc=`expr $perc + 20`
|
||||
done
|
||||
.Ed
|
||||
.Pp
|
||||
Gauge script:
|
||||
.Bd -literal -offset indent -compact
|
||||
@ -558,22 +614,6 @@ do
|
||||
i=`expr $i + 1`
|
||||
done | bsddialog --title Gauge --gauge "Starting..." 10 70
|
||||
.Ed
|
||||
.Pp
|
||||
Mixedgauge script:
|
||||
.Bd -literal -offset indent -compact
|
||||
perc=0
|
||||
while [ $perc -le 100 ]
|
||||
do
|
||||
bsddialog --sleep 1 --title Mixedgauge \e
|
||||
--mixedgauge "\enExample...\en" 0 0 $perc \e
|
||||
"Hidden" " -9" \e
|
||||
"Label 1" " -4" \e
|
||||
"Label 2" " -4" \e
|
||||
"Label 3" $perc
|
||||
|
||||
perc=`expr $perc + 20`
|
||||
done
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr bsddialog 3
|
||||
.Sh HISTORY
|
||||
@ -584,7 +624,99 @@ utility first appeared in
|
||||
.Sh AUTHORS
|
||||
.Nm bsddialog
|
||||
was written by
|
||||
.An Alfonso Sabato Siciliano Aq Mt alf.siciliano@gmail.com .
|
||||
.Sh BUGS
|
||||
Forms do not resize the dialog after a terminal change and do not provide
|
||||
scrolling for items.
|
||||
.An Alfonso Sabato Siciliano
|
||||
.Aq Mt asiciliano@FreeBSD.org .
|
||||
.Pp
|
||||
.Nm bsddialog
|
||||
provides a subset of the functionality described in the
|
||||
.Nm dialog
|
||||
manual.
|
||||
The following features were reimplemented:
|
||||
.Pp
|
||||
Common options:
|
||||
.Fl Fl ascii-lines ,
|
||||
.Fl Fl backtitle ,
|
||||
.Fl Fl cancel-label ,
|
||||
.Fl Fl clear ,
|
||||
.Fl Fl colors ,
|
||||
.Fl Fl cr-wrap ,
|
||||
.Fl Fl date-format ,
|
||||
.Fl Fl defaultno ,
|
||||
.Fl Fl default-button ,
|
||||
.Fl Fl default-no ,
|
||||
.Fl Fl default-item ,
|
||||
.Fl Fl exit-label ,
|
||||
.Fl Fl extra-button ,
|
||||
.Fl Fl extra-label ,
|
||||
.Fl Fl help ,
|
||||
.Fl Fl help-button ,
|
||||
.Fl Fl help-label ,
|
||||
.Fl Fl help-status ,
|
||||
.Fl Fl help-tags ,
|
||||
.Fl Fl hfile ,
|
||||
.Fl Fl hline ,
|
||||
.Fl Fl ignore ,
|
||||
.Fl Fl insecure ,
|
||||
.Fl Fl item-help ,
|
||||
.Fl Fl max-input ,
|
||||
.Fl Fl no-cancel ,
|
||||
.Fl Fl nocancel ,
|
||||
.Fl Fl no-collapse ,
|
||||
.Fl Fl no-items ,
|
||||
.Fl Fl no-label ,
|
||||
.Fl Fl no-lines ,
|
||||
.Fl Fl no-nl-expand ,
|
||||
.Fl Fl no-ok ,
|
||||
.Fl Fl nook ,
|
||||
.Fl Fl no-shadow ,
|
||||
.Fl Fl no-tags ,
|
||||
.Fl Fl ok-label ,
|
||||
.Fl Fl output-fd ,
|
||||
.Fl Fl output-separator ,
|
||||
.Fl Fl print-maxsize ,
|
||||
.Fl Fl print-size ,
|
||||
.Fl Fl print-version ,
|
||||
.Fl Fl quoted ,
|
||||
.Fl Fl separate-output ,
|
||||
.Fl Fl separator ,
|
||||
.Fl Fl shadow ,
|
||||
.Fl Fl single-quoted ,
|
||||
.Fl Fl sleep ,
|
||||
.Fl Fl stderr ,
|
||||
.Fl Fl stdout ,
|
||||
.Fl Fl tab-len ,
|
||||
.Fl Fl time-format ,
|
||||
.Fl Fl title ,
|
||||
.Fl Fl trim ,
|
||||
.Fl Fl version ,
|
||||
.Fl Fl yes-label .
|
||||
.Pp
|
||||
Dialogs:
|
||||
.Fl Fl checklist ,
|
||||
.Fl Fl form ,
|
||||
.Fl Fl gauge ,
|
||||
.Fl Fl infobox ,
|
||||
.Fl Fl inputbox ,
|
||||
.Fl Fl menu ,
|
||||
.Fl Fl mixedform ,
|
||||
.Fl Fl mixedgauge ,
|
||||
.Fl Fl msgbox ,
|
||||
.Fl Fl passwordbox ,
|
||||
.Fl Fl passwordform ,
|
||||
.Fl Fl pause ,
|
||||
.Fl Fl radiolist ,
|
||||
.Fl Fl rangebox ,
|
||||
.Fl Fl textbox ,
|
||||
.Fl Fl timebox ,
|
||||
.Fl Fl treeview ,
|
||||
.Fl Fl yesno .
|
||||
.Pp
|
||||
Some feature differs in input, output, or behavior.
|
||||
Compatibility is not a priority for future development.
|
||||
.Sh THANKS TO
|
||||
.An Baptiste Daroussin
|
||||
.Aq Mt bapt@FreeBSD.org
|
||||
and
|
||||
.An \&Ed Maste
|
||||
.Aq Mt emaste@FreeBSD.org
|
||||
for suggestions, help, and testing.
|
||||
|
@ -39,7 +39,9 @@
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_theme.h>
|
||||
|
||||
#define BSDDIALOG_VERSION "0.2"
|
||||
#include "util_theme.h"
|
||||
|
||||
#define BSDDIALOG_VERSION "0.3"
|
||||
|
||||
enum OPTS {
|
||||
/* Common options */
|
||||
@ -47,16 +49,18 @@ enum OPTS {
|
||||
BACKTITLE,
|
||||
BEGIN_X,
|
||||
BEGIN_Y,
|
||||
BIKESHED,
|
||||
CANCEL_LABEL,
|
||||
CLEAR,
|
||||
COLORS,
|
||||
COLUMNS_PER_ROW,
|
||||
CR_WRAP,
|
||||
DATE_FORMAT,
|
||||
DEFAULT_BUTTON,
|
||||
DEFAULT_ITEM,
|
||||
DEFAULT_NO,
|
||||
DISABLE_ESC,
|
||||
ESC_CANCELVALUE,
|
||||
ESC_RETURNCANCEL,
|
||||
EXIT_LABEL,
|
||||
EXTRA_BUTTON,
|
||||
EXTRA_LABEL,
|
||||
@ -75,6 +79,7 @@ enum OPTS {
|
||||
ITEM_DEPTH,
|
||||
ITEM_HELP,
|
||||
ITEM_PREFIX,
|
||||
LOAD_THEME,
|
||||
MAX_INPUT,
|
||||
NO_CANCEL,
|
||||
NO_COLLAPSE,
|
||||
@ -91,12 +96,14 @@ enum OPTS {
|
||||
PRINT_SIZE,
|
||||
PRINT_VERSION,
|
||||
QUOTED,
|
||||
SAVE_THEME,
|
||||
SEPARATE_OUTPUT,
|
||||
SHADOW,
|
||||
SINGLE_QUOTED,
|
||||
SLEEP,
|
||||
STDERR,
|
||||
STDOUT,
|
||||
SWITCH_BUTTONS,
|
||||
TAB_LEN,
|
||||
THEME,
|
||||
TIME_FORMAT,
|
||||
@ -136,15 +143,16 @@ static char *date_fmt_opt, *time_fmt_opt;
|
||||
static int unsigned max_input_form_opt;
|
||||
/* General options */
|
||||
static int output_fd_opt;
|
||||
bool bikeshed_opt;
|
||||
|
||||
/* Functions */
|
||||
static void sigint_handler(int sig);
|
||||
static void
|
||||
custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
|
||||
char *text, char *buf);
|
||||
|
||||
static void sigint_handler(int sig);
|
||||
|
||||
static void errorexit(char *errbuf);
|
||||
/* Dialogs */
|
||||
#define BUILDER_ARGS struct bsddialog_conf conf, char* text, int rows, \
|
||||
#define BUILDER_ARGS struct bsddialog_conf *conf, char* text, int rows, \
|
||||
int cols, int argc, char **argv, char *errbuf
|
||||
static int checklist_builder(BUILDER_ARGS);
|
||||
static int datebox_builder(BUILDER_ARGS);
|
||||
@ -176,23 +184,24 @@ static void usage(void)
|
||||
|
||||
printf("Common Options:\n");
|
||||
printf("--ascii-lines, --backtitle <backtitle>, --begin-x <x>, "
|
||||
"--begin-y <y>, --cancel-label <label>, --clear, --colors, "
|
||||
"--cr-wrap, --date-format <format>, --defaultno, "
|
||||
"--default-button <label>, --default-no, --default-item <name>, "
|
||||
"--disable-esc, --esc-cancelvalue, --exit-label <label>, "
|
||||
"--extra-button, --extra-label <label>, "
|
||||
"--generic-button1 <label>, --generic-button2 <label>, --help, "
|
||||
"--help-button, --help-label <label>, --help-status, --help-tags, "
|
||||
"--hfile <filename>, --hline <string>, --hmsg <string>, --ignore, "
|
||||
"--insecure, --item-depth, --item-help, --items-prefix, "
|
||||
"--max-input <size>, --no-cancel, --nocancel, --no-collapse, "
|
||||
"--no-items, --no-label <label>, --no-lines, --no-nl-expand, "
|
||||
"--no-ok, --nook, --no-shadow, --no-tags, --ok-label <label>, "
|
||||
"--output-fd <fd>, --output-separator <sep>, --print-maxsize, "
|
||||
"--print-size, --print-version, --quoted, --separate-output, "
|
||||
"--separator <sep>, --shadow, --single-quoted, --sleep <secs>, "
|
||||
"--stderr, --stdout, --tab-len <spaces>, "
|
||||
"--theme <blackwhite|bsddialog|flat|dialog>, "
|
||||
"--begin-y <y>, --bikeshed, --cancel-label <label>, --clear, "
|
||||
"--colors, --columns-per-row <columns>, --cr-wrap, "
|
||||
"--date-format <format>, --default-button <label>, "
|
||||
"--default-item <name>, --default-no, --disable-esc, "
|
||||
"--esc-return-cancel, --exit-label <label>, --extra-button, "
|
||||
"--extra-label <label>, --generic-button1 <label>, "
|
||||
"--generic-button2 <label>, --help, --help-button, "
|
||||
"--help-label <label>, --help-status, --help-tags, --hfile <file>, "
|
||||
"--hline <string>, --hmsg <string>, --ignore, --insecure, "
|
||||
"--item-depth, --item-help, --item-prefix, --load-theme <file>, "
|
||||
"--max-input <size>, --no-cancel, --no-collapse, --no-items, "
|
||||
"--no-label <label>, --no-lines, --no-nl-expand, --no-ok, "
|
||||
"--no-shadow, --no-tags, --ok-label <label>, --output-fd <fd>, "
|
||||
"--output-separator <sep>, --print-maxsize, --print-size, "
|
||||
"--print-version, --quoted, --save-theme <file>, "
|
||||
"--separate-output, --separator <sep>, --shadow, --single-quoted, "
|
||||
"--sleep <secs>, --stderr, --stdout, --tab-len <spaces>, "
|
||||
"--switch-buttons, --theme <blackwhite|bsddialog|flat|dialog>, "
|
||||
"--time-format <format>, --title <title>, --trim, --version, "
|
||||
"--yes-label <label>.\n");
|
||||
printf("\n");
|
||||
@ -202,14 +211,14 @@ static void usage(void)
|
||||
"<on|off>] ...\n");
|
||||
printf("--datebox <text> <rows> <cols> [<yy> <mm> <dd>]\n");
|
||||
printf("--form <text> <rows> <cols> <formrows> [<label> <ylabel> "
|
||||
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxvaluelen>] "
|
||||
"<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> <maxvaluelen> "
|
||||
"<xlabel> <init> <yfield> <xfield> <fieldlen> <maxletters> "
|
||||
"<0|1|2>] ...\n");
|
||||
printf("--mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
|
||||
"<miniperc>] ...\n");
|
||||
@ -217,7 +226,7 @@ static void usage(void)
|
||||
printf("--passwordbox <text> <rows> <cols> [init]\n");
|
||||
printf("--passwordform <text> <rows> <cols> <formrows> [<label> "
|
||||
"<ylabel> <xlabel> <init> <yfield> <xfield> <fieldlen> "
|
||||
"<maxvaluelen>] ...\n");
|
||||
"<maxletters>] ...\n");
|
||||
printf("--pause <text> <rows> <cols> <secs>\n");
|
||||
printf("--radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
|
||||
"<on|off>] ...\n");
|
||||
@ -235,11 +244,12 @@ static void usage(void)
|
||||
int main(int argc, char *argv[argc])
|
||||
{
|
||||
bool cr_wrap_opt, no_collapse_opt, no_nl_expand_opt, trim_opt;
|
||||
bool esc_cancelvalue_opt, ignore_opt, print_maxsize_opt;;
|
||||
int input, rows, cols, output, getH, getW;
|
||||
bool esc_return_cancel_opt, ignore_opt, print_maxsize_opt;
|
||||
bool textfromfile;
|
||||
int input, rows, cols, retval, getH, getW;
|
||||
int (*dialogbuilder)(BUILDER_ARGS) = NULL;
|
||||
enum bsddialog_default_theme theme_opt;
|
||||
char *text, *backtitle_opt;
|
||||
char *text, *backtitle_opt, *loadthemefile, *savethemefile;
|
||||
char errorbuilder[1024];
|
||||
struct winsize ws;
|
||||
struct bsddialog_conf conf;
|
||||
@ -250,7 +260,7 @@ int main(int argc, char *argv[argc])
|
||||
conf.key.enable_esc = true;
|
||||
conf.menu.on_without_ok = true;
|
||||
conf.form.value_without_ok = true;
|
||||
conf.form.enable_wchar = true;
|
||||
conf.button.always_active = true;
|
||||
|
||||
backtitle_opt = NULL;
|
||||
theme_opt = BSDDIALOG_THEME_FLAT;
|
||||
@ -258,8 +268,12 @@ int main(int argc, char *argv[argc])
|
||||
print_maxsize_opt = false;
|
||||
ignore_opt = false;
|
||||
cr_wrap_opt = no_collapse_opt = no_nl_expand_opt = trim_opt = false;
|
||||
esc_cancelvalue_opt = false;
|
||||
esc_return_cancel_opt = false;
|
||||
textfromfile = false;
|
||||
bikeshed_opt = false;
|
||||
errorbuilder[0] = '\0';
|
||||
savethemefile = NULL;
|
||||
loadthemefile = NULL;
|
||||
|
||||
item_output_sepnl_opt = item_singlequote_opt = false;
|
||||
item_prefix_opt = item_bottomdesc_opt = item_depth_opt = false;
|
||||
@ -279,6 +293,7 @@ int main(int argc, char *argv[argc])
|
||||
{"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-label", required_argument, NULL, CANCEL_LABEL},
|
||||
{"clear", no_argument, NULL, CLEAR},
|
||||
{"colors", no_argument, NULL, COLORS},
|
||||
@ -289,7 +304,7 @@ int main(int argc, char *argv[argc])
|
||||
{"default-item", required_argument, NULL, DEFAULT_ITEM},
|
||||
{"default-no", no_argument, NULL, DEFAULT_NO},
|
||||
{"disable-esc", no_argument, NULL, DISABLE_ESC},
|
||||
{"esc-cancelvalue", no_argument, NULL, ESC_CANCELVALUE},
|
||||
{"esc-return-cancel",no_argument, NULL, ESC_RETURNCANCEL},
|
||||
{"exit-label", required_argument, NULL, EXIT_LABEL},
|
||||
{"extra-button", no_argument, NULL, EXTRA_BUTTON},
|
||||
{"extra-label", required_argument, NULL, EXTRA_LABEL},
|
||||
@ -308,6 +323,7 @@ int main(int argc, char *argv[argc])
|
||||
{"item-depth", no_argument, NULL, ITEM_DEPTH},
|
||||
{"item-help", no_argument, NULL, ITEM_HELP},
|
||||
{"item-prefix", no_argument, NULL, ITEM_PREFIX},
|
||||
{"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},
|
||||
@ -327,6 +343,8 @@ int main(int argc, char *argv[argc])
|
||||
{"print-size", no_argument, NULL, PRINT_SIZE},
|
||||
{"print-version", no_argument, NULL, PRINT_VERSION},
|
||||
{"quoted", no_argument, NULL, QUOTED},
|
||||
{"columns-per-row", required_argument, NULL, COLUMNS_PER_ROW},
|
||||
{"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},
|
||||
@ -334,6 +352,7 @@ int main(int argc, char *argv[argc])
|
||||
{"sleep", required_argument, NULL, SLEEP},
|
||||
{"stderr", no_argument, NULL, STDERR},
|
||||
{"stdout", no_argument, NULL, STDOUT},
|
||||
{"switch-buttons", no_argument, NULL, SWITCH_BUTTONS},
|
||||
{"tab-len", required_argument, NULL, TAB_LEN},
|
||||
{"theme", required_argument, NULL, THEME},
|
||||
{"time-format", required_argument, NULL, TIME_FORMAT},
|
||||
@ -373,6 +392,8 @@ int main(int argc, char *argv[argc])
|
||||
break;
|
||||
case BACKTITLE:
|
||||
backtitle_opt = optarg;
|
||||
if (conf.y == BSDDIALOG_CENTER)
|
||||
conf.auto_topmargin = 2;
|
||||
break;
|
||||
case BEGIN_X:
|
||||
conf.x = (int)strtol(optarg, NULL, 10);
|
||||
@ -389,6 +410,10 @@ int main(int argc, char *argv[argc])
|
||||
conf.y, BSDDIALOG_CENTER);
|
||||
return (255);
|
||||
}
|
||||
conf.auto_topmargin = 0;
|
||||
break;
|
||||
case BIKESHED:
|
||||
bikeshed_opt = true;
|
||||
break;
|
||||
case CANCEL_LABEL:
|
||||
conf.button.cancel_label = optarg;
|
||||
@ -399,6 +424,10 @@ int main(int argc, char *argv[argc])
|
||||
case COLORS:
|
||||
conf.text.highlight = true;
|
||||
break;
|
||||
case COLUMNS_PER_ROW:
|
||||
conf.text.cols_per_row =
|
||||
(u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case CR_WRAP:
|
||||
cr_wrap_opt = true;
|
||||
break;
|
||||
@ -417,8 +446,8 @@ int main(int argc, char *argv[argc])
|
||||
case DISABLE_ESC:
|
||||
conf.key.enable_esc = false;
|
||||
break;
|
||||
case ESC_CANCELVALUE:
|
||||
esc_cancelvalue_opt = true;
|
||||
case ESC_RETURNCANCEL:
|
||||
esc_return_cancel_opt = true;
|
||||
break;
|
||||
case EXIT_LABEL:
|
||||
conf.button.ok_label = optarg;
|
||||
@ -454,7 +483,7 @@ int main(int argc, char *argv[argc])
|
||||
conf.key.f1_file = optarg;
|
||||
break;
|
||||
case HLINE:
|
||||
if (strlen(optarg) > 0)
|
||||
if (optarg[0] != '\0')
|
||||
conf.bottomtitle = optarg;
|
||||
break;
|
||||
case HMSG:
|
||||
@ -475,6 +504,9 @@ int main(int argc, char *argv[argc])
|
||||
case ITEM_PREFIX:
|
||||
item_prefix_opt = true;
|
||||
break;
|
||||
case LOAD_THEME:
|
||||
loadthemefile = optarg;
|
||||
break;
|
||||
case MAX_INPUT:
|
||||
max_input_form_opt = (u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
@ -524,6 +556,9 @@ int main(int argc, char *argv[argc])
|
||||
case PRINT_VERSION:
|
||||
printf("bsddialog version %s\n", BSDDIALOG_VERSION);
|
||||
break;
|
||||
case SAVE_THEME:
|
||||
savethemefile = optarg;
|
||||
break;
|
||||
case SEPARATE_OUTPUT:
|
||||
item_output_sepnl_opt = true;
|
||||
break;
|
||||
@ -542,6 +577,9 @@ int main(int argc, char *argv[argc])
|
||||
case STDOUT:
|
||||
output_fd_opt = STDOUT_FILENO;
|
||||
break;
|
||||
case SWITCH_BUTTONS:
|
||||
conf.button.always_active = false;
|
||||
break;
|
||||
case TAB_LEN:
|
||||
conf.text.tablen = (u_int)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
@ -575,12 +613,14 @@ int main(int argc, char *argv[argc])
|
||||
/* Dialogs */
|
||||
case CHECKLIST:
|
||||
dialogbuilder = checklist_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case DATEBOX:
|
||||
dialogbuilder = datebox_builder;
|
||||
break;
|
||||
case FORM:
|
||||
dialogbuilder = form_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case GAUGE:
|
||||
dialogbuilder = gauge_builder;
|
||||
@ -590,12 +630,15 @@ int main(int argc, char *argv[argc])
|
||||
break;
|
||||
case INPUTBOX:
|
||||
dialogbuilder = inputbox_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case MENU:
|
||||
dialogbuilder = menu_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case MIXEDFORM:
|
||||
dialogbuilder = mixedform_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case MIXEDGAUGE:
|
||||
dialogbuilder = mixedgauge_builder;
|
||||
@ -608,24 +651,29 @@ int main(int argc, char *argv[argc])
|
||||
break;
|
||||
case PASSWORDBOX:
|
||||
dialogbuilder = passwordbox_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case PASSWORDFORM:
|
||||
dialogbuilder = passwordform_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case RADIOLIST:
|
||||
dialogbuilder = radiolist_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case RANGEBOX:
|
||||
dialogbuilder = rangebox_builder;
|
||||
break;
|
||||
case TEXTBOX:
|
||||
dialogbuilder = textbox_builder;
|
||||
textfromfile = true;
|
||||
break;
|
||||
case TIMEBOX:
|
||||
dialogbuilder = timebox_builder;
|
||||
break;
|
||||
case TREEVIEW:
|
||||
dialogbuilder = treeview_builder;
|
||||
conf.auto_downmargin = 1;
|
||||
break;
|
||||
case YESNO:
|
||||
dialogbuilder = yesno_builder;
|
||||
@ -653,7 +701,7 @@ int main(int argc, char *argv[argc])
|
||||
usage();
|
||||
return (255);
|
||||
}
|
||||
if (dialogbuilder == textbox_builder)
|
||||
if (textfromfile) /* textbox */
|
||||
text = argv[0];
|
||||
else {
|
||||
if ((text = malloc(strlen(argv[0]) + 1)) == NULL) {
|
||||
@ -671,45 +719,52 @@ int main(int argc, char *argv[argc])
|
||||
/* bsddialog terminal mode */
|
||||
if (bsddialog_init() != 0) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (BSDDIALOG_ERROR);
|
||||
return (255);
|
||||
}
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
if (theme_opt != BSDDIALOG_THEME_FLAT)
|
||||
bsddialog_set_default_theme(theme_opt);
|
||||
if (bsddialog_set_default_theme(theme_opt) != BSDDIALOG_OK)
|
||||
errorexit(NULL);
|
||||
if (loadthemefile != NULL)
|
||||
if (loadtheme(loadthemefile, errorbuilder) != BSDDIALOG_OK)
|
||||
errorexit(errorbuilder);
|
||||
if (bikeshed_opt)
|
||||
if (bikeshed(&conf, errorbuilder) != BSDDIALOG_OK)
|
||||
errorexit(errorbuilder);
|
||||
|
||||
if (backtitle_opt != NULL)
|
||||
bsddialog_backtitle(&conf, backtitle_opt);
|
||||
if( bsddialog_backtitle(&conf, backtitle_opt))
|
||||
errorexit(NULL);
|
||||
|
||||
errorbuilder[0] = '\0';
|
||||
output = BSDDIALOG_OK;
|
||||
if (dialogbuilder != NULL)
|
||||
output = dialogbuilder(conf, text, rows, cols, argc, argv,
|
||||
if (dialogbuilder != NULL) {
|
||||
retval = dialogbuilder(&conf, text, rows, cols, argc, argv,
|
||||
errorbuilder);
|
||||
if (retval == BSDDIALOG_ERROR)
|
||||
errorexit(errorbuilder);
|
||||
} else
|
||||
retval = BSDDIALOG_OK;
|
||||
|
||||
if (dialogbuilder != textbox_builder)
|
||||
free(text);
|
||||
if (savethemefile != NULL)
|
||||
if (savetheme(savethemefile, errorbuilder, BSDDIALOG_VERSION) !=
|
||||
BSDDIALOG_OK)
|
||||
errorexit(errorbuilder);
|
||||
|
||||
bsddialog_end();
|
||||
/* end bsddialog terminal mode */
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
if (errorbuilder[0] != '\0')
|
||||
printf("Error: %s\n", errorbuilder);
|
||||
else
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (255);
|
||||
}
|
||||
if (textfromfile == false)
|
||||
free(text);
|
||||
|
||||
if (conf.get_height != NULL && conf.get_width != NULL)
|
||||
dprintf(output_fd_opt, "Dialog size: (%d - %d)\n",
|
||||
*conf.get_height, *conf.get_width);
|
||||
|
||||
if (output == BSDDIALOG_ESC && esc_cancelvalue_opt)
|
||||
output = BSDDIALOG_CANCEL;
|
||||
if (retval == BSDDIALOG_ESC && esc_return_cancel_opt)
|
||||
retval = BSDDIALOG_CANCEL;
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void sigint_handler(int sig)
|
||||
@ -719,6 +774,18 @@ void sigint_handler(int sig)
|
||||
exit(255);
|
||||
}
|
||||
|
||||
void errorexit(char *errbuf)
|
||||
{
|
||||
bsddialog_end();
|
||||
|
||||
if (errbuf != NULL && errbuf[0] != '\0')
|
||||
printf("Error: %s\n", errbuf);
|
||||
else
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
|
||||
exit(255);
|
||||
}
|
||||
|
||||
void
|
||||
custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
|
||||
char *text, char *buf)
|
||||
@ -781,7 +848,7 @@ int gauge_builder(BUILDER_ARGS)
|
||||
else
|
||||
perc = 0;
|
||||
|
||||
output = bsddialog_gauge(&conf, text, rows, cols, perc, STDIN_FILENO,
|
||||
output = bsddialog_gauge(conf, text, rows, cols, perc, STDIN_FILENO,
|
||||
"XXX");
|
||||
|
||||
return (output);
|
||||
@ -791,7 +858,7 @@ int infobox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
|
||||
output = bsddialog_infobox(&conf, text, rows, cols);
|
||||
output = bsddialog_infobox(conf, text, rows, cols);
|
||||
|
||||
return (output);
|
||||
}
|
||||
@ -827,7 +894,7 @@ int mixedgauge_builder(BUILDER_ARGS)
|
||||
minipercs[i] = (int)strtol(argv[i * 2 + 1], NULL, 10);
|
||||
}
|
||||
|
||||
output = bsddialog_mixedgauge(&conf, text, rows, cols, mainperc,
|
||||
output = bsddialog_mixedgauge(conf, text, rows, cols, mainperc,
|
||||
nminibars, minilabels, minipercs);
|
||||
|
||||
return (output);
|
||||
@ -837,7 +904,7 @@ int msgbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
|
||||
output = bsddialog_msgbox(&conf, text, rows, cols);
|
||||
output = bsddialog_msgbox(conf, text, rows, cols);
|
||||
|
||||
return (output);
|
||||
}
|
||||
@ -853,7 +920,7 @@ int pause_builder(BUILDER_ARGS)
|
||||
}
|
||||
|
||||
secs = (u_int)strtoul(argv[0], NULL, 10);
|
||||
output = bsddialog_pause(&conf, text, rows, cols, secs);
|
||||
output = bsddialog_pause(conf, text, rows, cols, secs);
|
||||
|
||||
return (output);
|
||||
}
|
||||
@ -879,7 +946,7 @@ int rangebox_builder(BUILDER_ARGS)
|
||||
else
|
||||
value = min;
|
||||
|
||||
output = bsddialog_rangebox(&conf, text, rows, cols, min, max, &value);
|
||||
output = bsddialog_rangebox(conf, text, rows, cols, min, max, &value);
|
||||
|
||||
dprintf(output_fd_opt, "%d", value);
|
||||
|
||||
@ -890,7 +957,7 @@ int textbox_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
|
||||
output = bsddialog_textbox(&conf, text, rows, cols);
|
||||
output = bsddialog_textbox(conf, text, rows, cols);
|
||||
|
||||
return (output);
|
||||
}
|
||||
@ -899,7 +966,7 @@ int yesno_builder(BUILDER_ARGS)
|
||||
{
|
||||
int output;
|
||||
|
||||
output = bsddialog_yesno(&conf, text, rows, cols);
|
||||
output = bsddialog_yesno(conf, text, rows, cols);
|
||||
|
||||
return (output);
|
||||
}
|
||||
@ -925,13 +992,11 @@ int datebox_builder(BUILDER_ARGS)
|
||||
dd = (u_int)strtoul(argv[2], NULL, 10);
|
||||
}
|
||||
|
||||
output = bsddialog_datebox(&conf, text, rows, cols, &yy, &mm, &dd);
|
||||
output = bsddialog_datebox(conf, text, rows, cols, &yy, &mm, &dd);
|
||||
if (output != BSDDIALOG_OK)
|
||||
return (output);
|
||||
|
||||
if (date_fmt_opt == NULL) {
|
||||
dprintf(output_fd_opt, "%u/%u/%u", yy, mm, dd);
|
||||
} else {
|
||||
if (date_fmt_opt != NULL) {
|
||||
time(&cal);
|
||||
localtm = localtime(&cal);
|
||||
localtm->tm_year = yy - 1900;
|
||||
@ -939,6 +1004,10 @@ int datebox_builder(BUILDER_ARGS)
|
||||
localtm->tm_mday = dd;
|
||||
strftime(stringdate, 1024, date_fmt_opt, localtm);
|
||||
dprintf(output_fd_opt, "%s", stringdate);
|
||||
} else if (bikeshed_opt && (dd % 2 == 0)) {
|
||||
dprintf(output_fd_opt, "%u/%u/%u", yy, mm, dd);
|
||||
} else {
|
||||
dprintf(output_fd_opt, "%u/%02u/%02u", yy, mm, dd);
|
||||
}
|
||||
|
||||
return (output);
|
||||
@ -964,13 +1033,11 @@ int timebox_builder(BUILDER_ARGS)
|
||||
ss = (u_int)strtoul(argv[2], NULL, 10);
|
||||
}
|
||||
|
||||
output = bsddialog_timebox(&conf, text, rows, cols, &hh, &mm, &ss);
|
||||
output = bsddialog_timebox(conf, text, rows, cols, &hh, &mm, &ss);
|
||||
if (output != BSDDIALOG_OK)
|
||||
return (output);
|
||||
|
||||
if (time_fmt_opt == NULL) {
|
||||
dprintf(output_fd_opt, "%u:%u:%u", hh, mm, ss);
|
||||
} else {
|
||||
if (time_fmt_opt != NULL) {
|
||||
time(&clock);
|
||||
localtm = localtime(&clock);
|
||||
localtm->tm_hour = hh;
|
||||
@ -978,6 +1045,10 @@ int timebox_builder(BUILDER_ARGS)
|
||||
localtm->tm_sec = ss;
|
||||
strftime(stringtime, 1024, time_fmt_opt, localtm);
|
||||
dprintf(output_fd_opt, "%s", stringtime);
|
||||
} else if (bikeshed_opt && (ss % 2 == 0)) {
|
||||
dprintf(output_fd_opt, "%u:%u:%u", hh, mm, ss);
|
||||
} else {
|
||||
dprintf(output_fd_opt, "%02u:%02u:%02u", hh, mm, ss);
|
||||
}
|
||||
|
||||
return (output);
|
||||
@ -1117,7 +1188,7 @@ int checklist_builder(BUILDER_ARGS)
|
||||
if (output != 0)
|
||||
return (output);
|
||||
|
||||
output = bsddialog_checklist(&conf, text, rows, cols, menurows, nitems,
|
||||
output = bsddialog_checklist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem);
|
||||
@ -1146,7 +1217,7 @@ int menu_builder(BUILDER_ARGS)
|
||||
if (output != 0)
|
||||
return (output);
|
||||
|
||||
output = bsddialog_menu(&conf, text, rows, cols, menurows, nitems,
|
||||
output = bsddialog_menu(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem);
|
||||
@ -1175,7 +1246,7 @@ int radiolist_builder(BUILDER_ARGS)
|
||||
if (output != 0)
|
||||
return (output);
|
||||
|
||||
output = bsddialog_radiolist(&conf, text, rows, cols, menurows, nitems,
|
||||
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem);
|
||||
@ -1204,10 +1275,10 @@ int treeview_builder(BUILDER_ARGS)
|
||||
if (output != 0)
|
||||
return (output);
|
||||
|
||||
conf.menu.no_name = true;
|
||||
conf.menu.align_left = true;
|
||||
conf->menu.no_name = true;
|
||||
conf->menu.align_left = true;
|
||||
|
||||
output = bsddialog_radiolist(&conf, text, rows, cols, menurows, nitems,
|
||||
output = bsddialog_radiolist(conf, text, rows, cols, menurows, nitems,
|
||||
items, &focusitem);
|
||||
|
||||
print_menu_items(output, nitems, items, focusitem);
|
||||
@ -1239,7 +1310,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
dprintf(output_fd_opt, "%ls\n", (wchar_t*)items[i].value);
|
||||
dprintf(output_fd_opt, "%s\n", items[i].value);
|
||||
free(items[i].value);
|
||||
}
|
||||
}
|
||||
@ -1257,7 +1328,6 @@ int form_builder(BUILDER_ARGS)
|
||||
}
|
||||
|
||||
formheight = (u_int)strtoul(argv[0], NULL, 10);
|
||||
flags = 0;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
@ -1280,13 +1350,13 @@ int form_builder(BUILDER_ARGS)
|
||||
valuelen = (int)strtol(argv[j++], NULL, 10);
|
||||
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
|
||||
|
||||
flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
|
||||
flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
|
||||
items[i].flags = flags;
|
||||
|
||||
items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
|
||||
}
|
||||
|
||||
output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items);
|
||||
print_form_items(output, nitems, items);
|
||||
free(items);
|
||||
@ -1303,14 +1373,16 @@ int inputbox_builder(BUILDER_ARGS)
|
||||
item.ylabel = 0;
|
||||
item.xlabel = 0;
|
||||
item.init = argc > 0 ? argv[0] : "";
|
||||
item.yfield = 1;
|
||||
item.xfield = 1;
|
||||
item.fieldlen = cols > 4 ? cols-4 : 25;
|
||||
item.yfield = 0;
|
||||
item.xfield = 0;
|
||||
item.fieldlen = 1;
|
||||
item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
|
||||
item.flags = 0;
|
||||
item.flags = BSDDIALOG_FIELDNOCOLOR;
|
||||
item.flags |= BSDDIALOG_FIELDCURSOREND;
|
||||
item.flags |= BSDDIALOG_FIELDEXTEND;
|
||||
item.bottomdesc = "";
|
||||
|
||||
output = bsddialog_form(&conf, text, rows, cols, 1, 1, &item);
|
||||
output = bsddialog_form(conf, text, rows, cols, 1, 1, &item);
|
||||
print_form_items(output, 1, &item);
|
||||
|
||||
return (output);
|
||||
@ -1350,7 +1422,7 @@ int mixedform_builder(BUILDER_ARGS)
|
||||
items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
|
||||
}
|
||||
|
||||
output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items);
|
||||
print_form_items(output, nitems, items);
|
||||
free(items);
|
||||
@ -1367,14 +1439,17 @@ int passwordbox_builder(BUILDER_ARGS)
|
||||
item.ylabel = 0;
|
||||
item.xlabel = 0;
|
||||
item.init = argc > 0 ? argv[0] : "";
|
||||
item.yfield = 1;
|
||||
item.xfield = 1;
|
||||
item.fieldlen = cols > 4 ? cols-4 : 25;
|
||||
item.yfield = 0;
|
||||
item.xfield = 0;
|
||||
item.fieldlen = 1;
|
||||
item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
|
||||
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);
|
||||
output = bsddialog_form(conf, text, rows, cols, 1, 1, &item);
|
||||
print_form_items(output, 1, &item);
|
||||
|
||||
return (output);
|
||||
@ -1422,7 +1497,7 @@ int passwordform_builder(BUILDER_ARGS)
|
||||
items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
|
||||
}
|
||||
|
||||
output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
|
||||
output = bsddialog_form(conf, text, rows, cols, formheight, nitems,
|
||||
items);
|
||||
print_form_items(output, nitems, items);
|
||||
free(items);
|
||||
|
@ -10,7 +10,9 @@
|
||||
|
||||
libpath=../lib
|
||||
examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
|
||||
datebox form formw timebox rangebox pause"
|
||||
datebox form timebox rangebox pause"
|
||||
|
||||
rm -f $examples
|
||||
|
||||
for e in $examples
|
||||
do
|
||||
|
@ -34,9 +34,7 @@ int main()
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "datebox";
|
||||
output = bsddialog_datebox(&conf,
|
||||
"TAB / RIGHT / LEFT to move,\nUP / DOWN to select time", 10, 35,
|
||||
&yy, &mm, &dd);
|
||||
output = bsddialog_datebox(&conf, "Example", 9, 35, &yy, &mm, &dd);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -21,21 +22,22 @@ int main()
|
||||
int i, output;
|
||||
struct bsddialog_conf conf;
|
||||
struct bsddialog_formitem items[3] = {
|
||||
{"Input:", 1, 1, "value", 1, 11, 30, 50, NULL, 0, "desc 1"},
|
||||
{"Input:", 2, 1, "read only", 2, 11, 30, 50, NULL, RO, "desc 2"},
|
||||
{"Password:", 3, 1, "", 3, 11, 30, 50, NULL, H, "desc 3"}
|
||||
{"Input:", 0, 0, "value", 0, 10, 30, 50, NULL, 0, "desc 1"},
|
||||
{"Input:", 1, 0, "read only", 1, 10, 30, 50, NULL, RO, "desc 2"},
|
||||
{"Password:", 2, 0, "", 2, 10, 30, 50, NULL, H, "desc 3"}
|
||||
};
|
||||
|
||||
/* Optional, unless for unicode/multicolum charachters */
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "form";
|
||||
conf.form.securech = '*';
|
||||
output = bsddialog_form(&conf, "Example", 10, 50, 3, 3, items);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
if (output == BSDDIALOG_ERROR) {
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Written in 2022 by Alfonso Sabato Siciliano.
|
||||
* To the extent possible under law, the author has dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty, see:
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <bsddialog.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define H BSDDIALOG_FIELDHIDDEN
|
||||
#define RO BSDDIALOG_FIELDREADONLY
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, output;
|
||||
struct bsddialog_conf conf;
|
||||
struct bsddialog_formitem items[3] = {
|
||||
{"Input:", 1, 1, "value", 1, 11, 30, 50, NULL, 0, "desc 1"},
|
||||
{"Input:", 2, 1, "read only", 2, 11, 30, 50, NULL, RO, "desc 2"},
|
||||
{"Password:", 3, 1, "", 3, 11, 30, 50, NULL, H, "desc 3"}
|
||||
};
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||
printf("Error: %s\n", bsddialog_geterror());
|
||||
return (1);
|
||||
}
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "form";
|
||||
conf.form.securech = '*';
|
||||
conf.form.enable_wchar = true;
|
||||
output = bsddialog_form(&conf, "Example", 10, 50, 3, 3, items);
|
||||
|
||||
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 \"%ls\"\n", items[i].label, (wchar_t*)items[i].value);
|
||||
free(items[i].value);
|
||||
}
|
||||
|
||||
return (output);
|
||||
}
|
@ -34,9 +34,7 @@ int main()
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
conf.title = "timebox";
|
||||
output = bsddialog_timebox(&conf,
|
||||
"TAB / RIGHT / LEFT to move,\nUP / DOWN to select time", 10, 35,
|
||||
&hh, &mm, &ss);
|
||||
output = bsddialog_timebox(&conf, "Example", 9, 35, &hh, &mm, &ss);
|
||||
|
||||
bsddialog_end();
|
||||
|
||||
|
@ -15,11 +15,11 @@
|
||||
: ${BSDDIALOG_ESC=5}
|
||||
|
||||
FORMS=$(./bsddialog --title " form " --form "Hello World!" 12 40 5 \
|
||||
Label1: 1 1 Value1 1 9 18 25 \
|
||||
Label2: 2 1 Value2 2 9 18 25 \
|
||||
Label3: 3 1 Value3 3 9 18 25 \
|
||||
Label4: 4 1 Value4 4 9 18 25 \
|
||||
Label5: 5 1 Value5 5 9 18 25 \
|
||||
Label1: 0 0 Value1 0 8 18 25 \
|
||||
Label2: 1 0 Value2 1 8 18 25 \
|
||||
Label3: 2 0 Value3 2 8 18 25 \
|
||||
Label4: 3 0 Value4 3 8 18 25 \
|
||||
Label5: 4 0 Value5 4 8 18 25 \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
FORMS=$(./bsddialog --insecure --title " mixedform " \
|
||||
--mixedform "Hello World!" 12 40 3 \
|
||||
Label: 1 1 Entry 1 11 18 25 0 \
|
||||
Label: 2 1 Read-Only 2 11 18 25 2 \
|
||||
Password: 3 1 "" 3 11 18 25 1 \
|
||||
Label: 0 0 Entry 0 10 18 25 0 \
|
||||
Label: 1 0 Read-Only 1 10 18 25 2 \
|
||||
Password: 2 0 "" 2 10 18 25 1 \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
|
@ -16,11 +16,11 @@
|
||||
|
||||
FORMS=$(./bsddialog --insecure --title " passwordform " \
|
||||
--passwordform "Example" 12 40 5 \
|
||||
Password1: 1 1 "" 1 12 18 25 \
|
||||
Password2: 2 1 "" 2 12 18 25 \
|
||||
Password3: 3 1 "" 3 12 18 25 \
|
||||
Password4: 4 1 "" 4 12 18 25 \
|
||||
Password5: 5 1 "" 5 12 18 25 \
|
||||
Password1: 0 0 "" 0 11 18 25 \
|
||||
Password2: 1 0 "" 1 11 18 25 \
|
||||
Password3: 2 0 "" 2 11 18 25 \
|
||||
Password4: 3 0 "" 3 11 18 25 \
|
||||
Password5: 4 0 "" 4 11 18 25 \
|
||||
3>&1 1>&2 2>&3 3>&-)
|
||||
|
||||
case $? in
|
||||
|
@ -3,16 +3,16 @@
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
VERSION = 0.2
|
||||
VERSION = 0.3
|
||||
LIBRARY = bsddialog
|
||||
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
|
||||
SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \
|
||||
messagebox.c textbox.c theme.c timebox.c
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
CFLAGS = -D_XOPEN_SOURCE_EXTENDED -Wall -Wextra -Wno-implicit-fallthrough \
|
||||
CFLAGS = -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE -D_GNU_SOURCE -Wall -Wextra -Wno-implicit-fallthrough \
|
||||
-Werror -fpic
|
||||
LDFLAGS = -lformw -lncursesw -ltinfo
|
||||
LDFLAGS = -lncursesw -ltinfo
|
||||
LIBFLAG = -shared
|
||||
|
||||
RM = rm -f
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Written in 2021 by Alfonso Sabato Siciliano
|
||||
|
||||
VERSION = 0.2
|
||||
VERSION = 0.3
|
||||
LIBRARY = bsddialog
|
||||
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||
LIBRARY_A = lib${LIBRARY:=.a}
|
||||
@ -14,7 +14,7 @@ OBJECTS = ${SOURCES:.c=.o}
|
||||
CFLAGS += -D_XOPEN_SOURCE_EXTENDED -fPIC -Wall -Wextra
|
||||
LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
|
||||
-Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION} \
|
||||
-L/usr/lib -lformw -lncursesw -ltinfow
|
||||
-L/usr/lib -lncursesw -ltinfow
|
||||
|
||||
.if defined(DEBUG)
|
||||
# `make -DDEBUG`
|
||||
|
@ -70,7 +70,7 @@ draw_bar(WINDOW *win, int y, int x, int barlen, int perc, bool withlabel,
|
||||
sprintf(labelstr, "%d", label);
|
||||
else
|
||||
sprintf(labelstr, "%3d%%", perc);
|
||||
stringlen = (int)strlen(labelstr);
|
||||
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 ) ?
|
||||
@ -109,7 +109,7 @@ bar_checksize(int rows, int cols, struct buttons *bs)
|
||||
|
||||
minwidth = 0;
|
||||
if (bs != NULL) /* gauge has not buttons */
|
||||
minwidth = buttons_width(*bs);
|
||||
minwidth = buttons_min_width(*bs);
|
||||
|
||||
minwidth = MAX(minwidth, MINBARWIDTH);
|
||||
minwidth += VBORDERS;
|
||||
@ -151,16 +151,14 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED);
|
||||
|
||||
mainloop = (fd < 0) ? false : true;
|
||||
|
||||
if (mainloop) {
|
||||
input = NULL;
|
||||
if (fd >= 0) {
|
||||
fd2 = dup(fd);
|
||||
input = fdopen(fd2, "r");
|
||||
if (input == NULL)
|
||||
if ((input = fdopen(fd2, "r")) == NULL)
|
||||
RETURN_ERROR("Cannot build FILE* from fd");
|
||||
} else
|
||||
input = NULL;
|
||||
}
|
||||
|
||||
mainloop = true;
|
||||
while (mainloop) {
|
||||
wrefresh(widget);
|
||||
prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-4,
|
||||
@ -168,6 +166,8 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
draw_borders(conf, bar, 3, w-6, RAISED);
|
||||
draw_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
|
||||
wrefresh(bar);
|
||||
if (input == NULL) /* that is fd < 0 */
|
||||
break;
|
||||
|
||||
while (true) {
|
||||
fscanf(input, "%s", inputbuf);
|
||||
@ -193,10 +193,11 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
if (strcmp(inputbuf, sep) == 0)
|
||||
break;
|
||||
strcpy(pntext, inputbuf);
|
||||
pntext += strlen(inputbuf);
|
||||
pntext += strlen(inputbuf); /* end string, no strlen */
|
||||
pntext[0] = ' ';
|
||||
pntext++;
|
||||
}
|
||||
pntext[0] = '\0';
|
||||
if (update_dialog(conf, shadow, widget, y, x, h, w, textpad,
|
||||
ntext, NULL, false) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
@ -216,7 +217,7 @@ 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, output, miniperc, y, x, h, w, ypad, max_minbarlen;
|
||||
int i, retval, miniperc, y, x, h, w, ypad, max_minbarlen;
|
||||
int htextpad, htext, wtext;
|
||||
int colorperc, red, green;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
@ -240,7 +241,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
|
||||
max_minbarlen = 0;
|
||||
for (i = 0; i < (int)nminibars; i++)
|
||||
max_minbarlen = MAX(max_minbarlen, (int)strlen(minilabels[i]));
|
||||
max_minbarlen = MAX(max_minbarlen, (int)strcols(minilabels[i]));
|
||||
max_minbarlen += 3 + 16; /* seps + [...] */
|
||||
max_minbarlen = MAX(max_minbarlen, MINMGBARWIDTH); /* mainbar */
|
||||
|
||||
@ -267,10 +268,10 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
output = new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
|
||||
retval = new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
|
||||
NULL, false);
|
||||
if (output == BSDDIALOG_ERROR)
|
||||
return (output);
|
||||
if (retval == BSDDIALOG_ERROR)
|
||||
return (retval);
|
||||
|
||||
/* mini bars */
|
||||
for (i = 0; i < (int)nminibars; i++) {
|
||||
@ -281,6 +282,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
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)
|
||||
@ -338,12 +340,12 @@ bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int mainperc, unsigned int nminibars,
|
||||
const char **minilabels, int *minipercs)
|
||||
{
|
||||
int output;
|
||||
int retval;
|
||||
|
||||
output = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
|
||||
retval = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
|
||||
minilabels, minipercs, false);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -352,7 +354,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
struct bsddialog_fileminibar *minibar)
|
||||
{
|
||||
bool update;
|
||||
int perc, output, *minipercs;
|
||||
int perc, retval, *minipercs;
|
||||
unsigned int i, mainperc, totaltodo;
|
||||
float readforsec;
|
||||
const char **minilabels;
|
||||
@ -371,7 +373,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
}
|
||||
|
||||
refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
|
||||
output = BSDDIALOG_OK;
|
||||
retval = BSDDIALOG_OK;
|
||||
i = 0;
|
||||
update = true;
|
||||
time(&told);
|
||||
@ -384,9 +386,9 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
time(&tnew);
|
||||
if (update || tnew > told + refresh) {
|
||||
output = do_mixedgauge(conf, text, rows, cols, mainperc,
|
||||
retval = do_mixedgauge(conf, text, rows, cols, mainperc,
|
||||
nminibar, minilabels, minipercs, true);
|
||||
if (output == BSDDIALOG_ERROR)
|
||||
if (retval == BSDDIALOG_ERROR)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
move(SCREENLINES - 1, 2);
|
||||
@ -421,7 +423,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
free(minilabels);
|
||||
free(minipercs);
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -430,7 +432,8 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
{
|
||||
bool loop, buttupdate, barupdate;
|
||||
int y, x, h, w;
|
||||
int input, currvalue, output, sizebar, bigchange, positions;
|
||||
int currvalue, retval, sizebar, bigchange, positions;
|
||||
wint_t input;
|
||||
float perc;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
struct buttons bs;
|
||||
@ -483,17 +486,18 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
wrefresh(bar);
|
||||
}
|
||||
|
||||
input = getch();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
*value = currvalue;
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -587,7 +591,7 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
@ -596,7 +600,7 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -604,7 +608,8 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int sec)
|
||||
{
|
||||
bool loop, buttupdate, barupdate;
|
||||
int output, y, x, h, w, input, tout, sizebar;
|
||||
int retval, y, x, h, w, tout, sizebar;
|
||||
wint_t input;
|
||||
float perc;
|
||||
WINDOW *widget, *textpad, *bar, *shadow;
|
||||
struct buttons bs;
|
||||
@ -650,11 +655,10 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
buttupdate = false;
|
||||
}
|
||||
|
||||
input = getch();
|
||||
if (input < 0) { /* timeout */
|
||||
if (get_wch(&input) == ERR) { /* timeout */
|
||||
tout--;
|
||||
if (tout < 0) {
|
||||
output = BSDDIALOG_TIMEOUT;
|
||||
retval = BSDDIALOG_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@ -665,12 +669,12 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -731,7 +735,7 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
@ -742,5 +746,5 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
delwin(bar);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
@ -22,13 +22,14 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 9, 2022
|
||||
.Dd August 29, 2022
|
||||
.Dt BSDDIALOG 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bsddialog_backtitle ,
|
||||
.Nm bsddialog_clearterminal ,
|
||||
.Nm bsddialog_color ,
|
||||
.Nm bsddialog_color_attrs ,
|
||||
.Nm bsddialog_checklist ,
|
||||
.Nm bsddialog_datebox ,
|
||||
.Nm bsddialog_end ,
|
||||
@ -36,8 +37,10 @@
|
||||
.Nm bsddialog_gauge ,
|
||||
.Nm bsddialog_geterror ,
|
||||
.Nm bsddialog_get_theme ,
|
||||
.Nm bsddialog_hascolors ,
|
||||
.Nm bsddialog_infobox ,
|
||||
.Nm bsddialog_init ,
|
||||
.Nm bsddialog_init_notheme ,
|
||||
.Nm bsddialog_initconf ,
|
||||
.Nm bsddialog_menu ,
|
||||
.Nm bsddialog_mixedgauge ,
|
||||
@ -115,6 +118,8 @@
|
||||
.Ft int
|
||||
.Fn bsddialog_init "void"
|
||||
.Ft int
|
||||
.Fn bsddialog_init_notheme "void"
|
||||
.Ft int
|
||||
.Fn bsddialog_initconf "struct bsddialog_conf *conf"
|
||||
.Ft int
|
||||
.Fo bsddialog_menu
|
||||
@ -218,7 +223,16 @@
|
||||
.Fa "unsigned int flags"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo bsddialog_color_attrs
|
||||
.Fa "int color"
|
||||
.Fa "enum bsddialog_color *foreground"
|
||||
.Fa "enum bsddialog_color *background"
|
||||
.Fa "unsigned int *flags"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn bsddialog_get_theme "struct bsddialog_theme *theme"
|
||||
.Ft bool
|
||||
.Fn bsddialog_hascolors "void"
|
||||
.Ft int
|
||||
.Fn bsddialog_set_default_theme "enum bsddialog_default_theme theme"
|
||||
.Ft int
|
||||
@ -239,6 +253,12 @@ API.
|
||||
restores the screen like before
|
||||
.Fn bsddialog_init ,
|
||||
then it is not possible to use the library functions.
|
||||
.Fn bsddialog_init_notheme
|
||||
is equivalent to
|
||||
.Fn bsddialog_init
|
||||
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
|
||||
@ -258,10 +278,9 @@ is described later.
|
||||
.Pp
|
||||
Each
|
||||
.Fa char*
|
||||
argument has to be a well terminated string, can be empty
|
||||
.Pq Dq
|
||||
but not
|
||||
.Dv NULL .
|
||||
argument has to be a well terminated string, it can be a multibyte character
|
||||
string depending on current locale, see
|
||||
.Xr setlocale 3 .
|
||||
.Ss Dialogs
|
||||
The dialogs have common arguments.
|
||||
.Fa text
|
||||
@ -282,6 +301,8 @@ struct bsddialog_conf {
|
||||
bool ascii_lines;
|
||||
unsigned int auto_minheight;
|
||||
unsigned int auto_minwidth;
|
||||
unsigned int auto_topmargin;
|
||||
unsigned int auto_downmargin;
|
||||
const char *bottomtitle;
|
||||
bool clear;
|
||||
int *get_height;
|
||||
@ -298,6 +319,7 @@ struct bsddialog_conf {
|
||||
const char *f1_message;
|
||||
} key;
|
||||
struct {
|
||||
unsigned int cols_per_row;
|
||||
bool highlight;
|
||||
unsigned int tablen;
|
||||
} text;
|
||||
@ -309,11 +331,13 @@ struct bsddialog_conf {
|
||||
bool shortcut_buttons;
|
||||
} menu;
|
||||
struct {
|
||||
bool enable_wchar;
|
||||
int securech;
|
||||
char securech;
|
||||
char *securembch;
|
||||
bool value_wchar;
|
||||
bool value_without_ok;
|
||||
} form;
|
||||
struct {
|
||||
bool always_active;
|
||||
bool without_ok;
|
||||
const char *ok_label;
|
||||
bool with_extra;
|
||||
@ -343,6 +367,23 @@ minimum width if
|
||||
.Fa cols
|
||||
is
|
||||
.Dv BSDDIALOG_AUTOSIZE .
|
||||
.It Fa conf.auto_topmargin
|
||||
top margin if
|
||||
.Fa rows
|
||||
is
|
||||
.Dv BSDDIALOG_AUTOSIZE
|
||||
or
|
||||
.Dv BSDDIALOG_FULLSCREEN ,
|
||||
.Fa conf.y
|
||||
has to be
|
||||
.Dv BSDDIALOG_CENTER .
|
||||
.It Fa conf.auto_downmargin
|
||||
down margin if
|
||||
.Fa rows
|
||||
is
|
||||
.Dv BSDDIALOG_AUTOSIZE
|
||||
or
|
||||
.Dv BSDDIALOG_FULLSCREEN .
|
||||
.It Fa conf.bottomtitle
|
||||
subtitle at the dialog bottom side.
|
||||
.It Fa conf.clear
|
||||
@ -382,11 +423,16 @@ file to open if F1 is pressed.
|
||||
message to display if F1 is pressed.
|
||||
.El
|
||||
.Pp
|
||||
.Fa conf.text.highlight
|
||||
.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
|
||||
.Dv 10 .
|
||||
.It Fa conf.text.highlight
|
||||
enables highlights for
|
||||
.Fa text ,
|
||||
properly the following sequences are considered escapes:
|
||||
.Bl -column -compact
|
||||
.It Dq \eZ0
|
||||
black.
|
||||
.It Dq \eZ1
|
||||
@ -404,7 +450,7 @@ cyan.
|
||||
.It Dq \eZ7
|
||||
white.
|
||||
.It Dq \eZr
|
||||
reverse colors between foreground and background.
|
||||
reverse foreground and background.
|
||||
.It Dq \eZR
|
||||
disable reverse.
|
||||
.It Dq \eZb
|
||||
@ -417,11 +463,22 @@ underline.
|
||||
disable underline.
|
||||
.It Dq \eZn
|
||||
disable each customization.
|
||||
.It Fa conf.text.tablen
|
||||
tab length for
|
||||
.Fa text
|
||||
argument and
|
||||
.Fn bsddialog_textbox
|
||||
function.
|
||||
.El
|
||||
.Fa conf.text.tablen
|
||||
tab length.
|
||||
.Pp
|
||||
.Bl -column -compact
|
||||
.It Fa conf.button.always_active
|
||||
buttons always active, avoidind focus switch between buttons and input fields or
|
||||
input boxes in
|
||||
.Fn bsddialog_form ,
|
||||
.Fn bsddialog_datebox
|
||||
and
|
||||
.Fn bsddialog_timebox .
|
||||
.It Fa conf.button.without_ok
|
||||
disable OK button.
|
||||
.It Fa conf.button.ok_label
|
||||
@ -598,8 +655,16 @@ enable shortcut keys on buttons, default on items.
|
||||
.El
|
||||
.Pp
|
||||
.Fn bsddialog_form
|
||||
builds a dialog to display a list of items to get strings in input, an item is
|
||||
defined like:
|
||||
builds a dialog to display an array of
|
||||
.Fa items
|
||||
of
|
||||
.Fa nitems
|
||||
elements to get strings in input.
|
||||
.Fa formrows
|
||||
specifies the graphical height for the box around the items,
|
||||
.Dv 0
|
||||
for autosizing.
|
||||
An item is defined like:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
struct bsddialog_formitem {
|
||||
@ -621,7 +686,7 @@ struct bsddialog_formitem {
|
||||
.Ed
|
||||
.Pp
|
||||
.Fa label
|
||||
describes the request, it is printed at the position
|
||||
is a string to describe the request, it is printed at the position
|
||||
.Fa ylabel
|
||||
and
|
||||
.Fa xlabel .
|
||||
@ -632,45 +697,43 @@ and
|
||||
.Fa fieldlen
|
||||
is its graphical width, while
|
||||
.Fa maxvalelen
|
||||
is the maximum length of the input string,
|
||||
is the maximum number of characters of the input string.
|
||||
.Fa init
|
||||
is the default value.
|
||||
is the default field value.
|
||||
If the OK button is pressed
|
||||
.Fa value
|
||||
is the allocated memory with the current field string.
|
||||
is the allocated memory with the current field string, its size depends on
|
||||
the current locale.
|
||||
.Fa flags
|
||||
is an OR value to set the
|
||||
.Dv BSDDIALOG_FIELDHIDDEN
|
||||
.Dv BSDDIALOG_FIELDHIDDEN ,
|
||||
.Dv BSDDIALOG_FIELDREADONLY ,
|
||||
.Dv BSDDIALOG_FIELDNOCOLOR ,
|
||||
.Dv BSDDIALOG_FIELDCURSOREND ,
|
||||
.Dv BSDDIALOG_FIELDEXTEND
|
||||
and
|
||||
.Dv BSDDIALOG_FIELDREADONLY
|
||||
.Dv BSDDIALOG_FIELDSINGLEBYTE .
|
||||
flags for the field.
|
||||
.Fa bottomdesc
|
||||
is printed on the bottom side of the screen if the item is focused.
|
||||
.Fa items
|
||||
is an array of items of
|
||||
.Fa nitems
|
||||
elements,
|
||||
.Fa formrows
|
||||
specifies the graphical fixed height for the items list;
|
||||
.Fa ylabel
|
||||
and
|
||||
.Fa yfield
|
||||
have to be between 1 and
|
||||
.Fa formrows .
|
||||
.Pp
|
||||
.Fn bsddialog_form
|
||||
can be customized by:
|
||||
.Bl -column -compact
|
||||
.It Fa conf.form.enable_wchar
|
||||
enables characters greater than 127 in the field,
|
||||
.Fa value
|
||||
is a pointer to allocated memory for a
|
||||
.Em wchar_t
|
||||
string.
|
||||
.It Fa conf.form.securech
|
||||
charachter to hide the input
|
||||
with
|
||||
charachter to hide the input with
|
||||
.Dv BSDDIALOG_FIELDHIDDEN .
|
||||
.It Fa conf.form.securembch
|
||||
multibyte charachter to hide the input with
|
||||
.Dv BSDDIALOG_FIELDHIDDEN ,
|
||||
.Fa conf.form.securech
|
||||
is ignored.
|
||||
.It Fa conf.form.value_wchar
|
||||
the allocated
|
||||
.Fa value
|
||||
is a
|
||||
.Em wchar_t*
|
||||
string.
|
||||
.It Fa conf.form.value_without_ok
|
||||
allocate memory and set
|
||||
.Fa value
|
||||
@ -747,8 +810,8 @@ struct bsddialog_theme {
|
||||
} screen;
|
||||
struct {
|
||||
int color;
|
||||
unsigned int h;
|
||||
unsigned int w;
|
||||
unsigned int y;
|
||||
unsigned int x;
|
||||
} shadow;
|
||||
struct {
|
||||
int color;
|
||||
@ -770,20 +833,23 @@ struct bsddialog_theme {
|
||||
int descsepcolor;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
int bottomdesccolor;
|
||||
} menu;
|
||||
struct {
|
||||
int f_fieldcolor;
|
||||
int fieldcolor;
|
||||
int readonlycolor;
|
||||
int bottomdesccolor;
|
||||
} form;
|
||||
struct {
|
||||
int f_color;
|
||||
int color;
|
||||
} bar;
|
||||
struct {
|
||||
unsigned int hmargin;
|
||||
int leftdelim;
|
||||
int rightdelim;
|
||||
unsigned int minmargin;
|
||||
unsigned int maxmargin;
|
||||
char leftdelim;
|
||||
char rightdelim;
|
||||
int delimcolor;
|
||||
int f_delimcolor;
|
||||
int color;
|
||||
@ -825,6 +891,8 @@ specifies OR-flags, possible values:
|
||||
.Dv BSDDIALOG_REVERSE
|
||||
and
|
||||
.Dv BSDDIALOG_UNDERLINE .
|
||||
.Fn bsddialog_color_attrs
|
||||
gets the properties of a color.
|
||||
.Pp
|
||||
.Fn bsddialog_set_theme
|
||||
sets
|
||||
@ -840,6 +908,13 @@ and
|
||||
.Dv BSDDIALOG_THEME_DIALOG ,
|
||||
they can be set via
|
||||
.Fn bsddialog_set_default_theme .
|
||||
.Pp
|
||||
.Fn bsddialog_hascolors
|
||||
returns
|
||||
.Dv true
|
||||
if the terminal provides colors,
|
||||
.Dv false
|
||||
otherwise.
|
||||
.Sh RETURN VALUES
|
||||
The functions return the value
|
||||
.Dv BSDDIALOG_ERROR
|
||||
@ -975,8 +1050,7 @@ for (i = 0; i < 3; i++) {
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr bsddialog 1 ,
|
||||
.Xr curses 3 ,
|
||||
.Xr ncurses 3
|
||||
.Xr curses 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm bsddialog
|
||||
@ -985,8 +1059,4 @@ library first appeared in
|
||||
.Sh AUTHORS
|
||||
.Nm bsddialog
|
||||
was written by
|
||||
.An Alfonso Sabato Siciliano Aq Mt alf.siciliano@gmail.com .
|
||||
.Sh BUGS
|
||||
.Fn bsddialog_form
|
||||
does not resize the dialog after a terminal resize and does not provide
|
||||
scrolling for items.
|
||||
.An Alfonso Sabato Siciliano Aq Mt asiciliano@FreeBSD.org .
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LIBBSDDIALOG_VERSION "0.2"
|
||||
#define LIBBSDDIALOG_VERSION "0.3"
|
||||
|
||||
/* Exit status */
|
||||
#define BSDDIALOG_ERROR -1
|
||||
@ -64,13 +64,19 @@
|
||||
#define BSDDIALOG_MG_PENDING -11
|
||||
|
||||
/* Form */
|
||||
#define BSDDIALOG_FIELDHIDDEN 1U
|
||||
#define BSDDIALOG_FIELDREADONLY 2U
|
||||
#define BSDDIALOG_FIELDHIDDEN 1U
|
||||
#define BSDDIALOG_FIELDREADONLY 2U
|
||||
#define BSDDIALOG_FIELDNOCOLOR 4U
|
||||
#define BSDDIALOG_FIELDCURSOREND 8U
|
||||
#define BSDDIALOG_FIELDEXTEND 16U
|
||||
#define BSDDIALOG_FIELDSINGLEBYTE 32U
|
||||
|
||||
struct bsddialog_conf {
|
||||
bool ascii_lines;
|
||||
unsigned int auto_minheight;
|
||||
unsigned int auto_minwidth;
|
||||
unsigned int auto_topmargin;
|
||||
unsigned int auto_downmargin;
|
||||
const char *bottomtitle;
|
||||
bool clear;
|
||||
int *get_height;
|
||||
@ -87,6 +93,7 @@ struct bsddialog_conf {
|
||||
const char *f1_message;
|
||||
} key;
|
||||
struct {
|
||||
unsigned int cols_per_row;
|
||||
bool highlight;
|
||||
unsigned int tablen;
|
||||
} text;
|
||||
@ -98,11 +105,13 @@ struct bsddialog_conf {
|
||||
bool shortcut_buttons;
|
||||
} menu;
|
||||
struct {
|
||||
bool enable_wchar;
|
||||
int securech;
|
||||
char securech;
|
||||
char *securembch;
|
||||
bool value_wchar;
|
||||
bool value_without_ok;
|
||||
} form;
|
||||
struct {
|
||||
bool always_active;
|
||||
bool without_ok;
|
||||
const char *ok_label;
|
||||
bool with_extra;
|
||||
@ -156,6 +165,7 @@ struct bsddialog_formitem {
|
||||
};
|
||||
|
||||
int bsddialog_init(void);
|
||||
int bsddialog_init_notheme(void);
|
||||
int bsddialog_end(void);
|
||||
int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle);
|
||||
int bsddialog_initconf(struct bsddialog_conf *conf);
|
||||
|
@ -39,8 +39,8 @@ struct bsddialog_theme {
|
||||
} screen;
|
||||
struct {
|
||||
int color;
|
||||
unsigned int h;
|
||||
unsigned int w;
|
||||
unsigned int y;
|
||||
unsigned int x;
|
||||
} shadow;
|
||||
struct {
|
||||
int color;
|
||||
@ -62,20 +62,23 @@ struct bsddialog_theme {
|
||||
int descsepcolor;
|
||||
int f_shortcutcolor;
|
||||
int shortcutcolor;
|
||||
int bottomdesccolor;
|
||||
} menu;
|
||||
struct {
|
||||
int f_fieldcolor;
|
||||
int fieldcolor;
|
||||
int readonlycolor;
|
||||
int bottomdesccolor;
|
||||
} form;
|
||||
struct {
|
||||
int f_color;
|
||||
int color;
|
||||
} bar;
|
||||
struct {
|
||||
unsigned int hmargin;
|
||||
int leftdelim;
|
||||
int rightdelim;
|
||||
unsigned int minmargin;
|
||||
unsigned int maxmargin;
|
||||
char leftdelim;
|
||||
char rightdelim;
|
||||
int delimcolor;
|
||||
int f_delimcolor;
|
||||
int color;
|
||||
@ -106,7 +109,11 @@ enum bsddialog_color {
|
||||
int
|
||||
bsddialog_color(enum bsddialog_color foreground,
|
||||
enum bsddialog_color background, unsigned int flags);
|
||||
int
|
||||
bsddialog_color_attrs(int color, enum bsddialog_color *foreground,
|
||||
enum bsddialog_color *background, unsigned int *flags);
|
||||
int bsddialog_get_theme(struct bsddialog_theme *theme);
|
||||
bool bsddialog_hascolors(void);
|
||||
int bsddialog_set_default_theme(enum bsddialog_default_theme theme);
|
||||
int bsddialog_set_theme(struct bsddialog_theme *theme);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,13 +39,13 @@ infobox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int htext, wtext;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, NULL, 0, SCREENCOLS/2,
|
||||
&htext, &wtext) != 0)
|
||||
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, 0, NULL);
|
||||
*w = widget_min_width(conf, wtext, TEXTHMARGINS + 1, NULL);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 0, false);
|
||||
|
@ -32,13 +32,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "bsddialog.h"
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
#define TABLEN 4 /* Default tab len */
|
||||
#define ERRBUFLEN 1024 /* Error buffer */
|
||||
#define ERRBUFLEN 1024 /* Error buffer len */
|
||||
|
||||
/* Error */
|
||||
static char errorbuffer[ERRBUFLEN];
|
||||
@ -53,12 +54,101 @@ void set_error_string(const char *str)
|
||||
strncpy(errorbuffer, str, ERRBUFLEN-1);
|
||||
}
|
||||
|
||||
/* Unicode */
|
||||
wchar_t* alloc_mbstows(const char *mbstring)
|
||||
{
|
||||
size_t charlen, nchar;
|
||||
mbstate_t mbs;
|
||||
const char *pmbstring;
|
||||
wchar_t *wstring;
|
||||
|
||||
nchar = 1;
|
||||
pmbstring = mbstring;
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
while ((charlen = mbrlen(pmbstring, MB_CUR_MAX, &mbs)) != 0 &&
|
||||
charlen != (size_t)-1 && charlen != (size_t)-2) {
|
||||
pmbstring += charlen;
|
||||
nchar++;
|
||||
}
|
||||
|
||||
if ((wstring = calloc(nchar, sizeof(wchar_t))) == NULL)
|
||||
return (NULL);
|
||||
mbstowcs(wstring, mbstring, nchar);
|
||||
|
||||
return (wstring);
|
||||
}
|
||||
|
||||
void mvwaddwch(WINDOW *w, int y, int x, wchar_t wch)
|
||||
{
|
||||
wchar_t ws[2];
|
||||
|
||||
ws[0] = wch;
|
||||
ws[1] = L'\0';
|
||||
mvwaddwstr(w, y, x, ws);
|
||||
|
||||
}
|
||||
|
||||
int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col)
|
||||
{
|
||||
bool multicol;
|
||||
int w;
|
||||
unsigned int ncol;
|
||||
size_t charlen, mb_cur_max;
|
||||
wchar_t wch;
|
||||
mbstate_t mbs;
|
||||
|
||||
multicol = false;
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
ncol = 0;
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
while ((charlen = mbrlen(mbstring, mb_cur_max, &mbs)) != 0 &&
|
||||
charlen != (size_t)-1 && charlen != (size_t)-2) {
|
||||
if (mbtowc(&wch, mbstring, mb_cur_max) < 0)
|
||||
return (-1);
|
||||
w = (wch == L'\t') ? TABSIZE : wcwidth(wch);
|
||||
ncol += (w < 0) ? 0 : w;
|
||||
if (w > 1 && wch != L'\t')
|
||||
multicol = true;
|
||||
mbstring += charlen;
|
||||
}
|
||||
|
||||
if (cols != NULL)
|
||||
*cols = ncol;
|
||||
if (has_multi_col != NULL)
|
||||
*has_multi_col = multicol;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
unsigned int strcols(const char *mbstring)
|
||||
{
|
||||
int w;
|
||||
unsigned int ncol;
|
||||
size_t charlen, mb_cur_max;
|
||||
wchar_t wch;
|
||||
mbstate_t mbs;
|
||||
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
ncol = 0;
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
while ((charlen = mbrlen(mbstring, mb_cur_max, &mbs)) != 0 &&
|
||||
charlen != (size_t)-1 && charlen != (size_t)-2) {
|
||||
if (mbtowc(&wch, mbstring, mb_cur_max) < 0)
|
||||
return (0);
|
||||
w = (wch == L'\t') ? TABSIZE : wcwidth(wch);
|
||||
ncol += (w < 0) ? 0 : w;
|
||||
mbstring += charlen;
|
||||
}
|
||||
|
||||
return (ncol);
|
||||
}
|
||||
|
||||
/* Clear */
|
||||
int hide_widget(int y, int x, int h, int w, bool withshadow)
|
||||
{
|
||||
WINDOW *clear;
|
||||
|
||||
if ((clear = newwin(h, w, y + t.shadow.h, x + t.shadow.w)) == NULL)
|
||||
if ((clear = newwin(h, w, y + t.shadow.y, x + t.shadow.x)) == NULL)
|
||||
RETURN_ERROR("Cannot hide the widget");
|
||||
wbkgd(clear, t.screen.color);
|
||||
|
||||
@ -101,7 +191,7 @@ int f1help(struct bsddialog_conf *conf)
|
||||
/* Buttons */
|
||||
static void
|
||||
draw_button(WINDOW *window, int y, int x, int size, const char *text,
|
||||
bool selected, bool shortcut)
|
||||
wchar_t first, bool selected, bool shortcut)
|
||||
{
|
||||
int i, color_arrows, color_shortkey, color_button;
|
||||
|
||||
@ -126,14 +216,14 @@ draw_button(WINDOW *window, int y, int x, int size, const char *text,
|
||||
mvwaddch(window, y, x + i, t.button.rightdelim);
|
||||
wattroff(window, color_arrows);
|
||||
|
||||
x = x + 1 + ((size - 2 - strlen(text))/2);
|
||||
x = x + 1 + ((size - 2 - strcols(text))/2);
|
||||
wattron(window, color_button);
|
||||
mvwaddstr(window, y, x, text);
|
||||
wattroff(window, color_button);
|
||||
|
||||
if (shortcut) {
|
||||
wattron(window, color_shortkey);
|
||||
mvwaddch(window, y, x, text[0]);
|
||||
mvwaddwch(window, y, x, first);
|
||||
wattroff(window, color_shortkey);
|
||||
}
|
||||
}
|
||||
@ -142,16 +232,28 @@ void
|
||||
draw_buttons(WINDOW *window, struct buttons bs, bool shortcut)
|
||||
{
|
||||
int i, x, startx, y, rows, cols;
|
||||
unsigned int newmargin, margin, wbuttons;
|
||||
|
||||
getmaxyx(window, rows, cols);
|
||||
y = rows - 2;
|
||||
|
||||
startx = cols/2 - buttons_width(bs)/2;
|
||||
newmargin = cols - VBORDERS - (bs.nbuttons * bs.sizebutton);
|
||||
newmargin /= (bs.nbuttons + 1);
|
||||
newmargin = MIN(newmargin, t.button.maxmargin);
|
||||
if (newmargin == 0) {
|
||||
margin = t.button.minmargin;
|
||||
wbuttons = buttons_min_width(bs);
|
||||
} else {
|
||||
margin = newmargin;
|
||||
wbuttons = bs.nbuttons * bs.sizebutton;
|
||||
wbuttons += (bs.nbuttons + 1) * margin;
|
||||
}
|
||||
|
||||
startx = (cols)/2 - wbuttons/2 + newmargin;
|
||||
for (i = 0; i < (int)bs.nbuttons; i++) {
|
||||
x = i * (bs.sizebutton + t.button.hmargin);
|
||||
x = i * (bs.sizebutton + margin);
|
||||
draw_button(window, y, startx + x, bs.sizebutton, bs.label[i],
|
||||
i == bs.curr, shortcut);
|
||||
bs.first[i], i == bs.curr, shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,6 +265,7 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs,
|
||||
#define SIZEBUTTON 8
|
||||
#define DEFAULT_BUTTON_LABEL BUTTON_OK_LABEL
|
||||
#define DEFAULT_BUTTON_VALUE BSDDIALOG_OK
|
||||
wchar_t first;
|
||||
|
||||
bs->nbuttons = 0;
|
||||
bs->curr = 0;
|
||||
@ -216,6 +319,11 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs,
|
||||
bs->nbuttons = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)bs->nbuttons; i++) {
|
||||
mbtowc(&first, bs->label[i], MB_CUR_MAX);
|
||||
bs->first[i] = first;
|
||||
}
|
||||
|
||||
if (conf->button.default_label != NULL) {
|
||||
for (i = 0; i < (int)bs->nbuttons; i++) {
|
||||
if (strcmp(conf->button.default_label,
|
||||
@ -224,31 +332,31 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs,
|
||||
}
|
||||
}
|
||||
|
||||
bs->sizebutton = MAX(SIZEBUTTON - 2, strlen(bs->label[0]));
|
||||
bs->sizebutton = MAX(SIZEBUTTON - 2, strcols(bs->label[0]));
|
||||
for (i = 1; i < (int)bs->nbuttons; i++)
|
||||
bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i]));
|
||||
bs->sizebutton = MAX(bs->sizebutton, strcols(bs->label[i]));
|
||||
bs->sizebutton += 2;
|
||||
}
|
||||
|
||||
int buttons_width(struct buttons bs)
|
||||
int buttons_min_width(struct buttons bs)
|
||||
{
|
||||
unsigned int width;
|
||||
|
||||
width = bs.nbuttons * bs.sizebutton;
|
||||
if (bs.nbuttons > 0)
|
||||
width += (bs.nbuttons - 1) * t.button.hmargin;
|
||||
width += (bs.nbuttons - 1) * t.button.minmargin;
|
||||
|
||||
return (width);
|
||||
}
|
||||
|
||||
bool shortcut_buttons(int key, struct buttons *bs)
|
||||
bool shortcut_buttons(wint_t key, struct buttons *bs)
|
||||
{
|
||||
bool match;
|
||||
unsigned int i;
|
||||
|
||||
match = false;
|
||||
for (i = 0; i < bs->nbuttons; i++) {
|
||||
if (tolower(key) == tolower(bs->label[i][0])) {
|
||||
if (towlower(key) == towlower(bs->first[i])) {
|
||||
bs->curr = i;
|
||||
match = true;
|
||||
break;
|
||||
@ -259,48 +367,51 @@ bool shortcut_buttons(int key, struct buttons *bs)
|
||||
}
|
||||
|
||||
/* Text */
|
||||
static bool is_text_attr(const char *text)
|
||||
static bool is_wtext_attr(const wchar_t *wtext)
|
||||
{
|
||||
if (strnlen(text, 3) < 3)
|
||||
if (wcsnlen(wtext, 3) < 3)
|
||||
return (false);
|
||||
|
||||
if (text[0] != '\\' || text[1] != 'Z')
|
||||
if (wtext[0] != L'\\' || wtext[1] != L'Z')
|
||||
return (false);
|
||||
|
||||
return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true);
|
||||
return (wcschr(L"nbBrRuU01234567", wtext[2]) == NULL ? false : true);
|
||||
}
|
||||
|
||||
static bool check_set_text_attr(WINDOW *win, char *text)
|
||||
static bool check_set_wtext_attr(WINDOW *win, wchar_t *wtext)
|
||||
{
|
||||
if (is_text_attr(text) == false)
|
||||
enum bsddialog_color bg;
|
||||
|
||||
if (is_wtext_attr(wtext) == false)
|
||||
return (false);
|
||||
|
||||
if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) {
|
||||
wattron(win, bsddialog_color(text[2] - '0', COLOR_WHITE, 0));
|
||||
if ((wtext[2] - L'0') >= 0 && (wtext[2] - L'0') < 8) {
|
||||
bsddialog_color_attrs(t.dialog.color, NULL, &bg, NULL);
|
||||
wattron(win, bsddialog_color(wtext[2] - L'0', bg, 0));
|
||||
return (true);
|
||||
}
|
||||
|
||||
switch (text[2]) {
|
||||
case 'n':
|
||||
switch (wtext[2]) {
|
||||
case L'n':
|
||||
wattron(win, t.dialog.color);
|
||||
wattrset(win, A_NORMAL);
|
||||
break;
|
||||
case 'b':
|
||||
case L'b':
|
||||
wattron(win, A_BOLD);
|
||||
break;
|
||||
case 'B':
|
||||
case L'B':
|
||||
wattroff(win, A_BOLD);
|
||||
break;
|
||||
case 'r':
|
||||
case L'r':
|
||||
wattron(win, A_REVERSE);
|
||||
break;
|
||||
case 'R':
|
||||
case L'R':
|
||||
wattroff(win, A_REVERSE);
|
||||
break;
|
||||
case 'u':
|
||||
case L'u':
|
||||
wattron(win, A_UNDERLINE);
|
||||
break;
|
||||
case 'U':
|
||||
case L'U':
|
||||
wattroff(win, A_UNDERLINE);
|
||||
break;
|
||||
}
|
||||
@ -308,21 +419,27 @@ static bool check_set_text_attr(WINDOW *win, char *text)
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* Word Wrapping */
|
||||
static void
|
||||
print_string(WINDOW *win, int *rows, int cols, int *y, int *x, char *str,
|
||||
print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
|
||||
bool color)
|
||||
{
|
||||
int i, j, len, reallen;
|
||||
int i, j, len, reallen, wc;
|
||||
wchar_t ws[2];
|
||||
|
||||
len = reallen = strlen(str);
|
||||
ws[1] = L'\0';
|
||||
|
||||
len = wcslen(str);
|
||||
if (color) {
|
||||
reallen = 0;
|
||||
i=0;
|
||||
while (i < len) {
|
||||
if (is_text_attr(str+i))
|
||||
reallen -= 3;
|
||||
if (is_wtext_attr(str+i) == false)
|
||||
reallen += wcwidth(str[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
reallen = wcswidth(str, len);
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
@ -336,13 +453,18 @@ print_string(WINDOW *win, int *rows, int cols, int *y, int *x, char *str,
|
||||
}
|
||||
j = *x;
|
||||
while (j < cols && i < len) {
|
||||
if (color && check_set_text_attr(win, str+i)) {
|
||||
if (color && check_set_wtext_attr(win, str+i)) {
|
||||
i += 3;
|
||||
} else if (j + wcwidth(str[i]) > cols) {
|
||||
break;
|
||||
} else {
|
||||
mvwaddch(win, *y, j, str[i]);
|
||||
/* inline mvwaddwch() for efficiency */
|
||||
ws[0] = str[i];
|
||||
mvwaddwstr(win, *y, j, ws);
|
||||
wc = wcwidth(str[i]);;
|
||||
reallen -= wc;
|
||||
j += wc;
|
||||
i++;
|
||||
reallen--;
|
||||
j++;
|
||||
*x = j;
|
||||
}
|
||||
}
|
||||
@ -354,35 +476,38 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
|
||||
{
|
||||
bool loop;
|
||||
int i, j, z, rows, cols, x, y, tablen;
|
||||
char *string;
|
||||
wchar_t *wtext, *string;
|
||||
|
||||
if ((string = malloc(strlen(text) + 1)) == NULL)
|
||||
if ((wtext = alloc_mbstows(text)) == NULL)
|
||||
RETURN_ERROR("Cannot allocate/print text in wchar_t*");
|
||||
|
||||
if ((string = calloc(wcslen(wtext) + 1, sizeof(wchar_t))) == NULL)
|
||||
RETURN_ERROR("Cannot build (analyze) text");
|
||||
|
||||
getmaxyx(pad, rows, cols);
|
||||
tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
|
||||
tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
|
||||
|
||||
i = j = x = y = 0;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
string[j] = text[i];
|
||||
string[j] = wtext[i];
|
||||
|
||||
if (strchr("\n\t ", string[j]) != NULL || string[j] == '\0') {
|
||||
string[j] = '\0';
|
||||
if (wcschr(L"\n\t ", string[j]) != NULL || string[j] == L'\0') {
|
||||
string[j] = L'\0';
|
||||
print_string(pad, &rows, cols, &y, &x, string,
|
||||
conf->text.highlight);
|
||||
}
|
||||
|
||||
switch (text[i]) {
|
||||
case '\0':
|
||||
switch (wtext[i]) {
|
||||
case L'\0':
|
||||
loop = false;
|
||||
break;
|
||||
case '\n':
|
||||
case L'\n':
|
||||
x = 0;
|
||||
y++;
|
||||
j = -1;
|
||||
break;
|
||||
case '\t':
|
||||
case L'\t':
|
||||
for (z = 0; z < tablen; z++) {
|
||||
if (x >= cols) {
|
||||
x = 0;
|
||||
@ -392,7 +517,7 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
|
||||
}
|
||||
j = -1;
|
||||
break;
|
||||
case ' ':
|
||||
case L' ':
|
||||
x++;
|
||||
if (x >= cols) {
|
||||
x = 0;
|
||||
@ -410,79 +535,133 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
|
||||
i++;
|
||||
}
|
||||
|
||||
free(wtext);
|
||||
free(string);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Autosize */
|
||||
static int
|
||||
text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows,
|
||||
int mincols, bool increasecols, int *h, int *w)
|
||||
{
|
||||
int i, j, z, x, y;
|
||||
int tablen, wordlen, maxwordlen, nword, maxwords, line, maxwidth;
|
||||
/* Text Autosize */
|
||||
#define NL -1
|
||||
#define WS -2
|
||||
#define TB -3
|
||||
|
||||
struct textproperties {
|
||||
int nword;
|
||||
int *words;
|
||||
#define NL -1
|
||||
#define WS -2
|
||||
uint8_t *wletters;
|
||||
int maxwordcols;
|
||||
int maxline;
|
||||
bool hasnewline;
|
||||
};
|
||||
|
||||
static int
|
||||
text_properties(struct bsddialog_conf *conf, const char *text,
|
||||
struct textproperties *tp)
|
||||
{
|
||||
int i, l, currlinecols, maxwords, wtextlen, tablen, wordcols;
|
||||
wchar_t *wtext;
|
||||
|
||||
tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
|
||||
|
||||
maxwords = 1024;
|
||||
if ((words = calloc(maxwords, sizeof(int))) == NULL)
|
||||
if ((tp->words = calloc(maxwords, sizeof(int))) == NULL)
|
||||
RETURN_ERROR("Cannot alloc memory for text autosize");
|
||||
|
||||
tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
|
||||
maxwidth = widget_max_width(conf) - HBORDERS - TEXTHMARGINS;
|
||||
if ((wtext = alloc_mbstows(text)) == NULL)
|
||||
RETURN_ERROR("Cannot allocate/autosize text in wchar_t*");
|
||||
wtextlen = wcslen(wtext);
|
||||
if ((tp->wletters = calloc(wtextlen, sizeof(uint8_t))) == NULL)
|
||||
RETURN_ERROR("Cannot allocate wletters for text autosizing");
|
||||
|
||||
nword = 0;
|
||||
wordlen = 0;
|
||||
maxwordlen = 0;
|
||||
i=0;
|
||||
while (true) {
|
||||
if (conf->text.highlight && is_text_attr(text + i)) {
|
||||
i += 3;
|
||||
tp->nword = 0;
|
||||
tp->maxline = 0;
|
||||
tp->maxwordcols = 0;
|
||||
tp->hasnewline = false;
|
||||
currlinecols = 0;
|
||||
wordcols = 0;
|
||||
l = 0;
|
||||
for (i = 0; i < wtextlen; i++) {
|
||||
if (conf->text.highlight && is_wtext_attr(wtext + i)) {
|
||||
i += 2; /* +1 for update statement */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nword + tablen + 1 >= maxwords) {
|
||||
if (tp->nword + 1 >= maxwords) {
|
||||
maxwords += 1024;
|
||||
words = realloc(words, maxwords * sizeof(int));
|
||||
if (words == NULL)
|
||||
tp->words = realloc(tp->words, maxwords * sizeof(int));
|
||||
if (tp->words == NULL)
|
||||
RETURN_ERROR("Cannot realloc memory for text "
|
||||
"autosize");
|
||||
}
|
||||
|
||||
if (text[i] == '\0') {
|
||||
words[nword] = wordlen;
|
||||
maxwordlen = MAX(wordlen, maxwordlen);
|
||||
break;
|
||||
}
|
||||
if (wcschr(L"\t\n ", wtext[i]) != NULL) {
|
||||
tp->maxwordcols = MAX(wordcols, tp->maxwordcols);
|
||||
|
||||
if (strchr("\t\n ", text[i]) != NULL) {
|
||||
maxwordlen = MAX(wordlen, maxwordlen);
|
||||
|
||||
if (wordlen != 0) {
|
||||
words[nword] = wordlen;
|
||||
nword++;
|
||||
wordlen = 0;
|
||||
if (wordcols != 0) {
|
||||
/* line */
|
||||
currlinecols += wordcols;
|
||||
/* word */
|
||||
tp->words[tp->nword] = wordcols;
|
||||
tp->nword += 1;
|
||||
wordcols = 0;
|
||||
}
|
||||
|
||||
if (text[i] == '\t') {
|
||||
for (j = 0; j < tablen; j++)
|
||||
words[nword + j] = 1;
|
||||
nword += tablen;
|
||||
} else {
|
||||
words[nword] = text[i] == '\n' ? NL : WS;
|
||||
nword++;
|
||||
switch (wtext[i]) {
|
||||
case L'\t':
|
||||
/* line */
|
||||
currlinecols += tablen;
|
||||
/* word */
|
||||
tp->words[tp->nword] = TB;
|
||||
break;
|
||||
case L'\n':
|
||||
/* line */
|
||||
tp->hasnewline = true;
|
||||
tp->maxline = MAX(tp->maxline, currlinecols);
|
||||
currlinecols = 0;
|
||||
/* word */
|
||||
tp->words[tp->nword] = NL;
|
||||
break;
|
||||
case L' ':
|
||||
/* line */
|
||||
currlinecols += 1;
|
||||
/* word */
|
||||
tp->words[tp->nword] = WS;
|
||||
break;
|
||||
}
|
||||
tp->nword += 1;
|
||||
} else {
|
||||
tp->wletters[l] = wcwidth(wtext[i]);
|
||||
wordcols += tp->wletters[l];
|
||||
l++;
|
||||
}
|
||||
else
|
||||
wordlen++;
|
||||
|
||||
i++;
|
||||
}
|
||||
/* word */
|
||||
if (wordcols != 0) {
|
||||
tp->words[tp->nword] = wordcols;
|
||||
tp->nword += 1;
|
||||
tp->maxwordcols = MAX(wordcols, tp->maxwordcols);
|
||||
}
|
||||
/* line */
|
||||
tp->maxline = MAX(tp->maxline, currlinecols);
|
||||
|
||||
free(wtext);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
text_autosize(struct bsddialog_conf *conf, struct textproperties *tp,
|
||||
int maxrows, int mincols, bool increasecols, int *h, int *w)
|
||||
{
|
||||
int i, j, x, y, z, l, line, maxwidth, tablen;
|
||||
|
||||
maxwidth = widget_max_width(conf) - HBORDERS - TEXTHMARGINS;
|
||||
tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
|
||||
|
||||
if (increasecols) {
|
||||
mincols = MAX(mincols, maxwordlen);
|
||||
mincols = MAX(mincols, tp->maxwordcols);
|
||||
mincols = MAX(mincols,
|
||||
(int)conf->auto_minwidth - HBORDERS - TEXTHMARGINS);
|
||||
mincols = MIN(mincols, maxwidth);
|
||||
@ -492,26 +671,50 @@ text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows,
|
||||
x = 0;
|
||||
y = 1;
|
||||
line=0;
|
||||
for (i = 0; i <= nword; i++) {
|
||||
if (words[i] == NL) {
|
||||
l = 0;
|
||||
for (i = 0; i < tp->nword; i++) {
|
||||
switch (tp->words[i]) {
|
||||
case TB:
|
||||
for (j = 0; j < tablen; j++) {
|
||||
if (x >= mincols) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
break;
|
||||
case NL:
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
else if (words[i] == WS) {
|
||||
break;
|
||||
case WS:
|
||||
x++;
|
||||
if (x >= mincols) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (words[i] + x <= mincols)
|
||||
x += words[i];
|
||||
else {
|
||||
for (z = words[i]; z > 0; ) {
|
||||
y++;
|
||||
x = MIN(mincols, z);
|
||||
z -= x;
|
||||
break;
|
||||
default:
|
||||
if (tp->words[i] + x <= mincols) {
|
||||
x += tp->words[i];
|
||||
for (z = 0 ; z != tp->words[i]; l++ )
|
||||
z += tp->wletters[l];
|
||||
} else if (tp->words[i] <= mincols) {
|
||||
y++;
|
||||
x = tp->words[i];
|
||||
for (z = 0 ; z != tp->words[i]; l++ )
|
||||
z += tp->wletters[l];
|
||||
} else {
|
||||
for (j = tp->words[i]; j > 0; ) {
|
||||
y = (x == 0) ? y : y + 1;
|
||||
z = 0;
|
||||
while (z != j && z < mincols) {
|
||||
z += tp->wletters[l];
|
||||
l++;
|
||||
}
|
||||
x = z;
|
||||
line = MAX(line, x);
|
||||
j -= z;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -520,16 +723,16 @@ text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows,
|
||||
|
||||
if (increasecols == false)
|
||||
break;
|
||||
if (y <= maxrows || mincols >= maxwidth)
|
||||
if (mincols >= maxwidth)
|
||||
break;
|
||||
if (line >= y * (int)conf->text.cols_per_row && y <= maxrows)
|
||||
break;
|
||||
mincols++;
|
||||
}
|
||||
|
||||
*h = (nword == 0 && words[0] == 0) ? 0 : y;
|
||||
*h = (tp->nword == 0) ? 0 : y;
|
||||
*w = MIN(mincols, line); /* wtext can be less than mincols */
|
||||
|
||||
free(words);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -537,13 +740,26 @@ 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 wbuttons, maxhtext;
|
||||
bool changewtext;
|
||||
int wbuttons, maxhtext;
|
||||
struct textproperties tp;
|
||||
|
||||
wbuttons = 0;
|
||||
if (bs != NULL)
|
||||
wbuttons = buttons_width(*bs);
|
||||
wbuttons = buttons_min_width(*bs);
|
||||
|
||||
/* Rows */
|
||||
if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
|
||||
maxhtext = widget_max_height(conf) - VBORDERS - rowsnotext;
|
||||
} else { /* fixed */
|
||||
maxhtext = rows - VBORDERS - rowsnotext;
|
||||
}
|
||||
if (bs != NULL)
|
||||
maxhtext -= 2;
|
||||
if (maxhtext <= 0)
|
||||
maxhtext = 1; /* text_autosize() computes always htext */
|
||||
|
||||
/* Cols */
|
||||
if (cols == BSDDIALOG_AUTOSIZE) {
|
||||
startwtext = MAX(startwtext, wbuttons - TEXTHMARGINS);
|
||||
changewtext = true;
|
||||
@ -555,45 +771,52 @@ text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
|
||||
changewtext = false;
|
||||
}
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
|
||||
maxhtext = widget_max_height(conf) - VBORDERS - rowsnotext;
|
||||
if (bs != NULL)
|
||||
maxhtext -= 2;
|
||||
} else { /* fixed */
|
||||
maxhtext = rows - VBORDERS - rowsnotext;
|
||||
if (bs != NULL)
|
||||
maxhtext -= 2;
|
||||
}
|
||||
|
||||
if (startwtext <= 0 && changewtext)
|
||||
startwtext = 1;
|
||||
if (maxhtext <= 0 || startwtext <= 0) {
|
||||
*htext = *wtext = 0;
|
||||
return (0);
|
||||
}
|
||||
if (startwtext <= 0)
|
||||
RETURN_ERROR("Fullscreen or fixed cols to print text <=0");
|
||||
|
||||
if (text_autosize(conf, text, maxhtext, startwtext, changewtext,
|
||||
htext, wtext) != 0)
|
||||
/* Sizing calculation */
|
||||
if (text_properties(conf, text, &tp) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (text_autosize(conf, &tp, maxhtext, startwtext, changewtext, htext,
|
||||
wtext) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
free(tp.words);
|
||||
free(tp.wletters);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Widget size and position */
|
||||
int widget_max_height(struct bsddialog_conf *conf)
|
||||
{
|
||||
int maxheight;
|
||||
|
||||
maxheight = conf->shadow ? SCREENLINES - (int)t.shadow.h : SCREENLINES;
|
||||
maxheight = conf->shadow ? SCREENLINES - (int)t.shadow.y : SCREENLINES;
|
||||
if (maxheight <= 0)
|
||||
RETURN_ERROR("Terminal too small, screen lines - shadow <= 0");
|
||||
|
||||
if (conf->y > 0) {
|
||||
if (conf->y != BSDDIALOG_CENTER && conf->auto_topmargin > 0)
|
||||
RETURN_ERROR("conf.y > 0 and conf->auto_topmargin > 0");
|
||||
else if (conf->y == BSDDIALOG_CENTER) {
|
||||
maxheight -= conf->auto_topmargin;
|
||||
if (maxheight <= 0)
|
||||
RETURN_ERROR("Terminal too small, screen lines - top "
|
||||
"margins <= 0");
|
||||
} else if (conf->y > 0) {
|
||||
maxheight -= conf->y;
|
||||
if (maxheight <= 0)
|
||||
RETURN_ERROR("Terminal too small, screen lines - "
|
||||
"shadow - y <= 0");
|
||||
}
|
||||
|
||||
maxheight -= conf->auto_downmargin;
|
||||
if (maxheight <= 0)
|
||||
RETURN_ERROR("Terminal too small, screen lines - Down margins "
|
||||
"<= 0");
|
||||
|
||||
return (maxheight);
|
||||
}
|
||||
|
||||
@ -601,7 +824,7 @@ int widget_max_width(struct bsddialog_conf *conf)
|
||||
{
|
||||
int maxwidth;
|
||||
|
||||
maxwidth = conf->shadow ? SCREENCOLS - (int)t.shadow.w : SCREENCOLS;
|
||||
maxwidth = conf->shadow ? SCREENCOLS - (int)t.shadow.x : SCREENCOLS;
|
||||
if (maxwidth <= 0)
|
||||
RETURN_ERROR("Terminal too small, screen cols - shadow <= 0");
|
||||
|
||||
@ -648,13 +871,13 @@ widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
|
||||
struct buttons *bs)
|
||||
|
||||
{
|
||||
int min, delimtitle;
|
||||
int min, delimtitle, wbottomtitle, wtitle;
|
||||
|
||||
min = 0;
|
||||
|
||||
/* buttons */
|
||||
if (bs != NULL)
|
||||
min += buttons_width(*bs);
|
||||
min += buttons_min_width(*bs);
|
||||
|
||||
/* text */
|
||||
if (wtext > 0)
|
||||
@ -666,12 +889,15 @@ widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
|
||||
/* title */
|
||||
if (conf->title != NULL) {
|
||||
delimtitle = t.dialog.delimtitle ? 2 : 0;
|
||||
min = MAX(min, (int)strlen(conf->title) + 2 + delimtitle);
|
||||
wtitle = strcols(conf->title);
|
||||
min = MAX(min, wtitle + 2 + delimtitle);
|
||||
}
|
||||
|
||||
/* bottom title */
|
||||
if (conf->bottomtitle != NULL)
|
||||
min = MAX(min, (int)strlen(conf->bottomtitle) + 4);
|
||||
if (conf->bottomtitle != NULL) {
|
||||
wbottomtitle = strcols(conf->bottomtitle);
|
||||
min = MAX(min, wbottomtitle + 4);
|
||||
}
|
||||
|
||||
/* dialog borders */
|
||||
min += VBORDERS;
|
||||
@ -722,8 +948,16 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
|
||||
int
|
||||
set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
|
||||
{
|
||||
if (conf->y == BSDDIALOG_CENTER)
|
||||
*y = SCREENLINES/2 - (h + t.shadow.h)/2;
|
||||
int hshadow = conf->shadow ? (int)t.shadow.y : 0;
|
||||
int wshadow = conf->shadow ? (int)t.shadow.x : 0;
|
||||
|
||||
if (conf->y == BSDDIALOG_CENTER) {
|
||||
*y = SCREENLINES/2 - (h + hshadow)/2;
|
||||
if (*y < (int)conf->auto_topmargin)
|
||||
*y = conf->auto_topmargin;
|
||||
if (*y + h + hshadow > SCREENLINES - (int)conf->auto_downmargin)
|
||||
*y = SCREENLINES - h - hshadow - conf->auto_downmargin;
|
||||
}
|
||||
else if (conf->y < BSDDIALOG_CENTER)
|
||||
RETURN_ERROR("Negative begin y (less than -1)");
|
||||
else if (conf->y >= SCREENLINES)
|
||||
@ -731,13 +965,13 @@ set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
|
||||
else
|
||||
*y = conf->y;
|
||||
|
||||
if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > SCREENLINES)
|
||||
if (*y + h + hshadow > SCREENLINES)
|
||||
RETURN_ERROR("The lower of the box under the terminal "
|
||||
"(begin Y + height (+ shadow) > terminal lines)");
|
||||
|
||||
|
||||
if (conf->x == BSDDIALOG_CENTER)
|
||||
*x = SCREENCOLS/2 - (w + t.shadow.w)/2;
|
||||
*x = SCREENCOLS/2 - (w + wshadow)/2;
|
||||
else if (conf->x < BSDDIALOG_CENTER)
|
||||
RETURN_ERROR("Negative begin x (less than -1)");
|
||||
else if (conf->x >= SCREENCOLS)
|
||||
@ -745,14 +979,14 @@ set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
|
||||
else
|
||||
*x = conf->x;
|
||||
|
||||
if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > SCREENCOLS)
|
||||
if ((*x + w + wshadow) > SCREENCOLS)
|
||||
RETURN_ERROR("The right of the box over the terminal "
|
||||
"(begin X + width (+ shadow) > terminal cols)");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Widgets builders */
|
||||
/* Widgets build, update, destroy */
|
||||
void
|
||||
draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols,
|
||||
enum elevation elev)
|
||||
@ -816,7 +1050,7 @@ static int
|
||||
draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
WINDOW *textpad, const char *text, struct buttons *bs, bool shortcutbuttons)
|
||||
{
|
||||
int h, w, ts, ltee, rtee;
|
||||
int h, w, wtitle, wbottomtitle, ts, ltee, rtee;
|
||||
|
||||
ts = conf->ascii_lines ? '-' : ACS_HLINE;
|
||||
ltee = conf->ascii_lines ? '+' : ACS_LTEE;
|
||||
@ -830,13 +1064,15 @@ draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
draw_borders(conf, widget, h, w, RAISED);
|
||||
|
||||
if (conf->title != NULL) {
|
||||
if ((wtitle = strcols(conf->title)) < 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (t.dialog.delimtitle && conf->no_lines == false) {
|
||||
wattron(widget, t.dialog.lineraisecolor);
|
||||
mvwaddch(widget, 0, w/2-strlen(conf->title)/2-1, rtee);
|
||||
mvwaddch(widget, 0, w/2 - wtitle/2 -1, rtee);
|
||||
wattroff(widget, t.dialog.lineraisecolor);
|
||||
}
|
||||
wattron(widget, t.dialog.titlecolor);
|
||||
mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title);
|
||||
mvwaddstr(widget, 0, w/2 - wtitle/2, conf->title);
|
||||
wattroff(widget, t.dialog.titlecolor);
|
||||
if (t.dialog.delimtitle && conf->no_lines == false) {
|
||||
wattron(widget, t.dialog.lineraisecolor);
|
||||
@ -860,8 +1096,10 @@ draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
}
|
||||
|
||||
if (conf->bottomtitle != NULL) {
|
||||
if ((wbottomtitle = strcols(conf->bottomtitle)) < 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
wattron(widget, t.dialog.bottomtitlecolor);
|
||||
wmove(widget, h - 1, w/2 - strlen(conf->bottomtitle)/2 - 1);
|
||||
wmove(widget, h - 1, w/2 - wbottomtitle/2 - 1);
|
||||
waddch(widget, ' ');
|
||||
waddstr(widget, conf->bottomtitle);
|
||||
waddch(widget, ' ');
|
||||
@ -886,7 +1124,7 @@ update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
|
||||
if (conf->shadow) {
|
||||
wclear(shadow);
|
||||
mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
|
||||
mvwin(shadow, y + t.shadow.y, x + t.shadow.x);
|
||||
wresize(shadow, h, w);
|
||||
}
|
||||
|
||||
@ -913,7 +1151,7 @@ new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y,
|
||||
int error;
|
||||
|
||||
if (conf->shadow) {
|
||||
*shadow = newwin(h, w, y + t.shadow.h, x + t.shadow.w);
|
||||
*shadow = newwin(h, w, y + t.shadow.y, x + t.shadow.x);
|
||||
if (*shadow == NULL)
|
||||
RETURN_ERROR("Cannot build shadow");
|
||||
wbkgd(*shadow, t.shadow.color);
|
||||
|
@ -33,8 +33,9 @@
|
||||
#define TEXTHMARGIN 1
|
||||
#define TEXTHMARGINS (TEXTHMARGIN + TEXTHMARGIN)
|
||||
|
||||
/* current theme */
|
||||
/* theme utils */
|
||||
extern struct bsddialog_theme t;
|
||||
extern bool hastermcolors;
|
||||
|
||||
/* debug */
|
||||
#define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \
|
||||
@ -42,6 +43,12 @@ extern struct bsddialog_theme t;
|
||||
refresh(); \
|
||||
} while (0)
|
||||
|
||||
/* unicode */
|
||||
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);
|
||||
@ -56,6 +63,7 @@ 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 */
|
||||
@ -70,8 +78,8 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs,
|
||||
void
|
||||
draw_buttons(WINDOW *window, struct buttons bs, bool shortcut);
|
||||
|
||||
int buttons_width(struct buttons bs);
|
||||
bool shortcut_buttons(int key, struct buttons *bs);
|
||||
int buttons_min_width(struct buttons bs);
|
||||
bool shortcut_buttons(wint_t key, struct buttons *bs);
|
||||
|
||||
/* help window with F1 key */
|
||||
int f1help(struct bsddialog_conf *conf);
|
||||
@ -130,4 +138,4 @@ void
|
||||
end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
|
||||
WINDOW *textpad);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -34,10 +34,11 @@
|
||||
#include "bsddialog_theme.h"
|
||||
#include "lib_util.h"
|
||||
|
||||
int bsddialog_init(void)
|
||||
#define COLSPERROW 10 /* Default conf.text.columns_per_row */
|
||||
|
||||
int bsddialog_init_notheme(void)
|
||||
{
|
||||
int i, j, c, error;
|
||||
enum bsddialog_default_theme theme;
|
||||
|
||||
set_error_string("");
|
||||
|
||||
@ -64,7 +65,18 @@ int bsddialog_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (error == OK && has_colors())
|
||||
hastermcolors = (error == OK && has_colors()) ? true : false;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_init(void)
|
||||
{
|
||||
enum bsddialog_default_theme theme;
|
||||
|
||||
bsddialog_init_notheme();
|
||||
|
||||
if (bsddialog_hascolors())
|
||||
theme = BSDDIALOG_THEME_FLAT;
|
||||
else
|
||||
theme = BSDDIALOG_THEME_BLACKWHITE;
|
||||
@ -113,6 +125,7 @@ int bsddialog_initconf(struct bsddialog_conf *conf)
|
||||
conf->y = BSDDIALOG_CENTER;
|
||||
conf->x = BSDDIALOG_CENTER;
|
||||
conf->shadow = true;
|
||||
conf->text.cols_per_row = COLSPERROW;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
@ -177,9 +177,10 @@ getfastprev(int menurows, struct privateitem *pritems, int abs)
|
||||
|
||||
static int
|
||||
getnextshortcut(struct bsddialog_conf *conf, int npritems,
|
||||
struct privateitem *pritems, int abs, int key)
|
||||
struct privateitem *pritems, int abs, wint_t key)
|
||||
{
|
||||
int i, ch, next;
|
||||
int i, next;
|
||||
wchar_t wch;
|
||||
|
||||
next = -1;
|
||||
for (i = 0; i < npritems; i++) {
|
||||
@ -187,11 +188,11 @@ getnextshortcut(struct bsddialog_conf *conf, int npritems,
|
||||
continue;
|
||||
|
||||
if (conf->menu.no_name)
|
||||
ch = pritems[i].item->desc[0];
|
||||
mbtowc(&wch, pritems[i].item->desc, MB_CUR_MAX);
|
||||
else
|
||||
ch = pritems[i].item->name[0];
|
||||
mbtowc(&wch, pritems[i].item->name, MB_CUR_MAX);
|
||||
|
||||
if (ch == key) {
|
||||
if (wch == (wchar_t)key) {
|
||||
if (i > abs)
|
||||
return (i);
|
||||
|
||||
@ -236,12 +237,12 @@ drawseparators(struct bsddialog_conf *conf, WINDOW *pad, int linelen,
|
||||
}
|
||||
name = pritems[i].item->name;
|
||||
desc = pritems[i].item->desc;
|
||||
labellen = strlen(name) + strlen(desc) + 1;
|
||||
labellen = strcols(name) + strcols(desc) + 1;
|
||||
wmove(pad, i, labellen < linelen ? linelen/2 - labellen/2 : 0);
|
||||
wattron(pad, t.menu.namesepcolor);
|
||||
waddstr(pad, name);
|
||||
wattroff(pad, t.menu.namesepcolor);
|
||||
if (strlen(name) > 0 && strlen(desc) > 0)
|
||||
if (strcols(name) > 0 && strcols(desc) > 0)
|
||||
waddch(pad, ' ');
|
||||
wattron(pad, t.menu.descsepcolor);
|
||||
waddstr(pad, desc);
|
||||
@ -254,7 +255,7 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
|
||||
struct lineposition pos, struct privateitem *pritem, bool focus)
|
||||
{
|
||||
int colordesc, colorname, colorshortcut;
|
||||
const char *shortcut;
|
||||
wchar_t shortcut;
|
||||
struct bsddialog_menuitem *item;
|
||||
|
||||
item = pritem->item;
|
||||
@ -303,24 +304,47 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
|
||||
wattron(pad, colorshortcut);
|
||||
|
||||
if (conf->menu.no_name)
|
||||
shortcut = item->desc;
|
||||
mbtowc(&shortcut, item->desc, MB_CUR_MAX);
|
||||
else
|
||||
shortcut = item->name;
|
||||
wmove(pad, y, pos.xname + item->depth * DEPTH);
|
||||
if (shortcut != NULL && shortcut[0] != '\0')
|
||||
waddch(pad, shortcut[0]);
|
||||
wattroff(pad, colorshortcut);
|
||||
mbtowc(&shortcut, item->name, MB_CUR_MAX);
|
||||
mvwaddwch(pad, y, pos.xname + item->depth * DEPTH, shortcut);
|
||||
wattroff(pad, colorshortcut);
|
||||
}
|
||||
|
||||
/* bottom description */
|
||||
move(SCREENLINES - 1, 2);
|
||||
clrtoeol();
|
||||
if (item->bottomdesc != NULL && focus) {
|
||||
attron(t.menu.bottomdesccolor);
|
||||
addstr(item->bottomdesc);
|
||||
attroff(t.menu.bottomdesccolor);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */
|
||||
static void
|
||||
update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
|
||||
int totnitems, unsigned int menurows, int ymenupad)
|
||||
{
|
||||
draw_borders(conf, menuwin, h, w, LOWERED);
|
||||
|
||||
if (totnitems > (int)menurows) {
|
||||
wattron(menuwin, t.dialog.arrowcolor);
|
||||
if (ymenupad > 0)
|
||||
mvwhline(menuwin, 0, 2,
|
||||
conf->ascii_lines ? '^' : ACS_UARROW, 3);
|
||||
|
||||
if ((ymenupad + (int)menurows) < totnitems)
|
||||
mvwhline(menuwin, h-1, 2,
|
||||
conf->ascii_lines ? 'v' : ACS_DARROW, 3);
|
||||
|
||||
mvwprintw(menuwin, h-1, w-6, "%3d%%",
|
||||
100 * (ymenupad + menurows) / totnitems);
|
||||
wattroff(menuwin, t.dialog.arrowcolor);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
|
||||
const char *text, int linelen, unsigned int *menurows, int nitems,
|
||||
@ -365,8 +389,12 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
|
||||
*/
|
||||
*menurows = MIN(*h - 6 - htext, (int)*menurows);
|
||||
} else {
|
||||
if (*menurows == 0)
|
||||
*menurows = MIN(*h-6-htext, nitems);
|
||||
if (*menurows == 0) {
|
||||
if (*h - 6 - htext <= 0)
|
||||
*menurows = 0; /* menu_checksize() will check */
|
||||
else
|
||||
*menurows = MIN(*h-6-htext, nitems);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -380,8 +408,7 @@ menu_checksize(int rows, int cols, const char *text, int menurows, int nitems,
|
||||
|
||||
mincols = VBORDERS;
|
||||
/* buttons */
|
||||
mincols += buttons_width(bs);
|
||||
|
||||
mincols += buttons_min_width(bs);
|
||||
/*
|
||||
* linelen check, comment to allow some hidden col otherwise portconfig
|
||||
* could not show big menus like www/apache24
|
||||
@ -392,11 +419,11 @@ menu_checksize(int rows, int cols, const char *text, int menurows, int nitems,
|
||||
RETURN_ERROR("Few cols, width < size buttons or "
|
||||
"name + descripion of the items");
|
||||
|
||||
textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
|
||||
textrow = text != NULL && text[0] != '\0' ? 1 : 0;
|
||||
|
||||
if (nitems > 0 && menurows == 0)
|
||||
RETURN_ERROR("items > 0 but menurows == 0, probably terminal "
|
||||
"too small");
|
||||
RETURN_ERROR("items > 0 but menurows == 0, if menurows = 0 "
|
||||
"terminal too small");
|
||||
|
||||
menusize = nitems > 0 ? 3 : 0;
|
||||
if (rows < 2 + 2 + menusize + textrow)
|
||||
@ -405,37 +432,15 @@ menu_checksize(int rows, int cols, const char *text, int menurows, int nitems,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */
|
||||
static void
|
||||
update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
|
||||
int totnitems, unsigned int menurows, int ymenupad)
|
||||
{
|
||||
draw_borders(conf, menuwin, h, w, LOWERED);
|
||||
|
||||
if (totnitems > (int)menurows) {
|
||||
wattron(menuwin, t.dialog.arrowcolor);
|
||||
|
||||
if (ymenupad > 0)
|
||||
mvwprintw(menuwin, 0, 2, "^^^");
|
||||
|
||||
if ((ymenupad + (int)menurows) < totnitems)
|
||||
mvwprintw(menuwin, h-1, 2, "vvv");
|
||||
|
||||
wattroff(menuwin, t.dialog.arrowcolor);
|
||||
|
||||
mvwprintw(menuwin, h-1, w-10, "%3d%%",
|
||||
100 * (ymenupad + menurows) / totnitems);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
unsigned int menurows, enum menumode mode, unsigned int ngroups,
|
||||
struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
|
||||
{
|
||||
bool loop, onetrue, movefocus, automenurows, shortcut_butts;
|
||||
int i, j, y, x, h, w, output, input;
|
||||
int i, j, y, x, h, w, retval;
|
||||
int ymenupad, ys, ye, xs, xe, abs, next, totnitems;
|
||||
wint_t input;
|
||||
WINDOW *shadow, *widget, *textpad, *menuwin, *menupad;
|
||||
struct buttons bs;
|
||||
struct lineposition pos = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
@ -458,14 +463,14 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
|
||||
if (groups[i].type == BSDDIALOG_SEPARATOR) {
|
||||
pos.maxsepstr = MAX(pos.maxsepstr,
|
||||
strlen(item->name) + strlen(item->desc));
|
||||
strcols(item->name) + strcols(item->desc));
|
||||
continue;
|
||||
}
|
||||
|
||||
pos.maxprefix = MAX(pos.maxprefix,strlen(item->prefix));
|
||||
pos.maxprefix = MAX(pos.maxprefix,strcols(item->prefix));
|
||||
pos.maxdepth = MAX(pos.maxdepth, item->depth);
|
||||
pos.maxname = MAX(pos.maxname, strlen(item->name));
|
||||
pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc));
|
||||
pos.maxname = MAX(pos.maxname, strcols(item->name));
|
||||
pos.maxdesc = MAX(pos.maxdesc, strcols(item->desc));
|
||||
}
|
||||
}
|
||||
pos.maxname = conf->menu.no_name ? 0 : pos.maxname;
|
||||
@ -479,7 +484,6 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
pos.xdesc += (pos.maxname != 0 ? 1 : 0);
|
||||
pos.line = MAX(pos.maxsepstr + 3, pos.xdesc + pos.maxdesc);
|
||||
|
||||
|
||||
get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
@ -498,11 +502,11 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
|
||||
doupdate();
|
||||
|
||||
prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
|
||||
y + h - menurows, x + 1 + w - TEXTHMARGIN);
|
||||
prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN, y + h - menurows,
|
||||
x + 1 + w - TEXTHMARGIN);
|
||||
|
||||
menuwin = new_boxed_window(conf, y + h - 5 - menurows, x + 2,
|
||||
menurows+2, w-4, LOWERED);
|
||||
menurows + 2, w - 4, LOWERED);
|
||||
|
||||
menupad = newpad(totnitems, pos.line);
|
||||
wbkgd(menupad, t.dialog.color);
|
||||
@ -562,22 +566,23 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
movefocus = false;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
input = getch();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
if (abs >= 0 && pritems[abs].type == MENUMODE)
|
||||
pritems[abs].on = true;
|
||||
set_on_output(conf, output, ngroups, groups, pritems);
|
||||
set_on_output(conf, retval, ngroups, groups, pritems);
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
if (abs >= 0 && pritems[abs].type == MENUMODE)
|
||||
pritems[abs].on = true;
|
||||
set_on_output(conf, output, ngroups, groups,
|
||||
set_on_output(conf, retval, ngroups, groups,
|
||||
pritems);
|
||||
loop = false;
|
||||
}
|
||||
@ -714,10 +719,10 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
default:
|
||||
if (shortcut_butts) {
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
if (pritems[abs].type == MENUMODE)
|
||||
pritems[abs].on = true;
|
||||
set_on_output(conf, output, ngroups,
|
||||
set_on_output(conf, retval, ngroups,
|
||||
groups, pritems);
|
||||
loop = false;
|
||||
}
|
||||
@ -728,7 +733,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
next = getnextshortcut(conf, totnitems, pritems, abs,
|
||||
input);
|
||||
movefocus = next != abs;
|
||||
}
|
||||
} /* end switch handler */
|
||||
|
||||
if (movefocus) {
|
||||
drawitem(conf, menupad, abs, pos, &pritems[abs], false);
|
||||
@ -744,7 +749,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
|
||||
movefocus = false;
|
||||
}
|
||||
}
|
||||
} /* end while handler */
|
||||
|
||||
if (focuslist != NULL)
|
||||
*focuslist = abs < 0 ? -1 : pritems[abs].group;
|
||||
@ -756,7 +761,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
free(pritems);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* API */
|
||||
@ -765,12 +770,12 @@ bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int menurows, unsigned int ngroups,
|
||||
struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
|
||||
{
|
||||
int output;
|
||||
int retval;
|
||||
|
||||
output = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE,
|
||||
retval = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE,
|
||||
ngroups, groups, focuslist, focusitem);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -778,14 +783,14 @@ bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int menurows, unsigned int nitems,
|
||||
struct bsddialog_menuitem *items, int *focusitem)
|
||||
{
|
||||
int output, focuslist = 0;
|
||||
int retval, focuslist = 0;
|
||||
struct bsddialog_menugroup group = {
|
||||
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
|
||||
|
||||
output = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE,
|
||||
retval = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE,
|
||||
1, &group, &focuslist, focusitem);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -793,14 +798,14 @@ bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int menurows, unsigned int nitems,
|
||||
struct bsddialog_menuitem *items, int *focusitem)
|
||||
{
|
||||
int output, focuslist = 0;
|
||||
int retval, focuslist = 0;
|
||||
struct bsddialog_menugroup group = {
|
||||
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
|
||||
|
||||
output = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1,
|
||||
retval = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1,
|
||||
&group, &focuslist, focusitem);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -808,12 +813,12 @@ bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
int cols, unsigned int menurows, unsigned int nitems,
|
||||
struct bsddialog_menuitem *items, int *focusitem)
|
||||
{
|
||||
int output, focuslist = 0;
|
||||
int retval, focuslist = 0;
|
||||
struct bsddialog_menugroup group = {
|
||||
BSDDIALOG_RADIOLIST /* unused */, nitems, items};
|
||||
|
||||
output = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE,
|
||||
retval = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE,
|
||||
1, &group, &focuslist, focusitem);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
@ -31,18 +31,22 @@
|
||||
#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, struct buttons bs)
|
||||
int *w, const char *text, bool *hastext, struct buttons bs)
|
||||
{
|
||||
int htext, wtext;
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
|
||||
if (text_size(conf, rows, cols, text, &bs, 0, SCREENCOLS/2,
|
||||
&htext, &wtext) != 0)
|
||||
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 (cols == BSDDIALOG_AUTOSIZE)
|
||||
@ -54,34 +58,40 @@ message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int message_checksize(int rows, int cols, struct buttons bs)
|
||||
static int
|
||||
message_checksize(int rows, int cols, bool hastext, struct buttons bs)
|
||||
{
|
||||
int mincols;
|
||||
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_width(bs);
|
||||
mincols += buttons_min_width(bs);
|
||||
|
||||
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 height 4");
|
||||
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");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
textupdate(WINDOW *widget, WINDOW *textpad, int htextpad, int ytextpad)
|
||||
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 (htextpad > h - 4) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -92,15 +102,16 @@ static int
|
||||
do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
struct buttons bs)
|
||||
{
|
||||
bool loop;
|
||||
int y, x, h, w, input, output, ytextpad, htextpad, unused;
|
||||
bool hastext, loop;
|
||||
int y, x, h, w, retval, ytextpad, htextpad, unused;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
wint_t input;
|
||||
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
|
||||
if (message_autosize(conf, rows, cols, &h, &w, text, &hastext, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_checksize(h, w, bs) != 0)
|
||||
if (message_checksize(h, w, hastext, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
@ -112,20 +123,21 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
ytextpad = 0;
|
||||
getmaxyx(textpad, htextpad, unused);
|
||||
unused++; /* fix unused error */
|
||||
textupdate(widget, textpad, htextpad, ytextpad);
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
loop = true;
|
||||
while (loop) {
|
||||
doupdate();
|
||||
input = getch();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch (input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -163,9 +175,9 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_autosize(conf, rows, cols, &h, &w, text,
|
||||
bs) != 0)
|
||||
NULL, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (message_checksize(h, w, bs) != 0)
|
||||
if (message_checksize(h, w, hastext, bs) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
@ -175,7 +187,8 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
getmaxyx(textpad, htextpad, unused);
|
||||
textupdate(widget, textpad, htextpad, ytextpad);
|
||||
ytextpad = 0;
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
|
||||
/* Important to fix grey lines expanding screen */
|
||||
refresh();
|
||||
@ -184,17 +197,17 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
if (ytextpad == 0)
|
||||
break;
|
||||
ytextpad--;
|
||||
textupdate(widget, textpad, htextpad, ytextpad);
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (ytextpad + h - 4 >= htextpad)
|
||||
break;
|
||||
ytextpad++;
|
||||
textupdate(widget, textpad, htextpad, ytextpad);
|
||||
textupdate(widget, textpad, htextpad, ytextpad, hastext);
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
@ -202,7 +215,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
|
||||
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* API */
|
||||
|
@ -28,18 +28,61 @@
|
||||
#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)
|
||||
{
|
||||
int h, w;
|
||||
chtype arrowch, borderch;
|
||||
|
||||
getmaxyx(widget, h, w);
|
||||
|
||||
if (conf->no_lines)
|
||||
borderch = ' ';
|
||||
else if (conf->ascii_lines)
|
||||
borderch = '|';
|
||||
else
|
||||
borderch = ACS_VLINE;
|
||||
|
||||
if (xpad > 0) {
|
||||
arrowch = conf->ascii_lines ? '<' : ACS_LARROW;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.arrowcolor;
|
||||
} else {
|
||||
arrowch = borderch;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.lineraisecolor;
|
||||
}
|
||||
mvwvline(widget, (h / 2) - 2, 0, arrowch, 4);
|
||||
|
||||
if (xpad + w-2-padmargin < wpad) {
|
||||
arrowch = conf->ascii_lines ? '>' : ACS_RARROW;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.arrowcolor;
|
||||
} else {
|
||||
arrowch = borderch;
|
||||
arrowch |= A_ATTRIBUTES & t.dialog.linelowercolor;
|
||||
}
|
||||
mvwvline(widget, (h / 2) - 2, 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
textbox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, int hpad, int wpad, struct buttons bs)
|
||||
int *w, int hpad, int wpad, int padmargin, struct buttons bs)
|
||||
{
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, 0, wpad, &bs);
|
||||
*w = widget_min_width(conf, 0, wpad + padmargin, &bs);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, 0, hpad, true);
|
||||
@ -50,7 +93,8 @@ textbox_checksize(int rows, int cols, int hpad, struct buttons bs)
|
||||
{
|
||||
int mincols;
|
||||
|
||||
mincols = VBORDERS + bs.sizebutton;
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_min_width(bs);
|
||||
|
||||
if (cols < mincols)
|
||||
RETURN_ERROR("Few cols for the textbox");
|
||||
@ -66,9 +110,11 @@ int
|
||||
bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
int cols)
|
||||
{
|
||||
bool loop;
|
||||
int i, output, input;
|
||||
int y, x, h, w, hpad, wpad, ypad, xpad, ys, ye, xs, xe, printrows;
|
||||
bool loop, has_multi_col;
|
||||
int i, retval, y, x, h, w;
|
||||
int hpad, wpad, ypad, xpad, ys, ye, xs, xe, padmargin, printrows;
|
||||
unsigned int defaulttablen, linecols;
|
||||
wint_t input;
|
||||
char buf[BUFSIZ];
|
||||
FILE *fp;
|
||||
struct buttons bs;
|
||||
@ -77,14 +123,19 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
if ((fp = fopen(file, "r")) == NULL)
|
||||
RETURN_ERROR("Cannot open file");
|
||||
|
||||
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;
|
||||
i = 0;
|
||||
while (fgets(buf, BUFSIZ, fp) != NULL) {
|
||||
if ((int) strlen(buf) > wpad) {
|
||||
wpad = strlen(buf);
|
||||
if (str_props(buf, &linecols, &has_multi_col) != 0)
|
||||
continue;
|
||||
if ((int)linecols > wpad) {
|
||||
wpad = linecols;
|
||||
wresize(pad, hpad, wpad);
|
||||
}
|
||||
if (i > hpad-1) {
|
||||
@ -93,20 +144,19 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
}
|
||||
mvwaddstr(pad, i, 0, buf);
|
||||
i++;
|
||||
if (has_multi_col)
|
||||
padmargin = 2;
|
||||
}
|
||||
fclose(fp);
|
||||
set_tabsize(defaulttablen);
|
||||
|
||||
bs.nbuttons = 1;
|
||||
bs.label[0] = "EXIT";
|
||||
if (conf->button.ok_label != NULL)
|
||||
bs.label[0] = conf->button.ok_label;
|
||||
bs.value[0] = BSDDIALOG_OK;
|
||||
get_buttons(conf, &bs, "EXIT", NULL);
|
||||
bs.curr = 0;
|
||||
bs.sizebutton = strlen(bs.label[0]) + 2;
|
||||
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, bs);
|
||||
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)
|
||||
@ -117,26 +167,33 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
ys = y + 1;
|
||||
xs = x + 1;
|
||||
xs = (padmargin == 0) ? x + 1 : x + 2;
|
||||
ye = ys + h - 5;
|
||||
xe = xs + w - 3;
|
||||
xe = xs + w - 3 - padmargin;
|
||||
ypad = xpad = 0;
|
||||
printrows = h-4;
|
||||
loop = true;
|
||||
while (loop) {
|
||||
wnoutrefresh(widget);
|
||||
pnoutrefresh(pad, ypad, xpad, ys, xs, ye, xe);
|
||||
doupdate();
|
||||
input = getch();
|
||||
updateborders(conf, widget, padmargin, hpad, wpad, ypad, xpad);
|
||||
/*
|
||||
* 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);
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
output = BSDDIALOG_OK;
|
||||
retval = BSDDIALOG_OK;
|
||||
loop = false;
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -164,7 +221,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'l':
|
||||
xpad = (xpad + w-2) < wpad-1 ? xpad + 1 : xpad;
|
||||
xpad = (xpad + w-2-padmargin) < wpad ? xpad + 1 : xpad;
|
||||
break;
|
||||
case KEY_UP:
|
||||
case 'k':
|
||||
@ -189,16 +246,16 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad,
|
||||
bs);
|
||||
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 = x + 1;
|
||||
xs = (padmargin == 0) ? x + 1 : x + 2;
|
||||
ye = ys + h - 5;
|
||||
xe = xs + w - 3;
|
||||
xe = xs + w - 3 - padmargin;
|
||||
ypad = xpad = 0;
|
||||
printrows = h - 4;
|
||||
|
||||
@ -211,7 +268,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
@ -219,5 +276,5 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
|
||||
|
||||
end_dialog(conf, shadow, widget, pad);
|
||||
|
||||
return (output);
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
@ -34,51 +34,53 @@
|
||||
#define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
|
||||
|
||||
struct bsddialog_theme t;
|
||||
bool hastermcolors;
|
||||
|
||||
static struct bsddialog_theme bsddialogtheme = {
|
||||
#define bgwidget COLOR_WHITE
|
||||
#define bgcurr COLOR_YELLOW
|
||||
.screen.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.h = 1,
|
||||
.shadow.w = 2,
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = true,
|
||||
.dialog.titlecolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||
.dialog.lineraisecolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.dialog.linelowercolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.dialog.color = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.dialog.arrowcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||
.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, bgcurr),
|
||||
.menu.selectorcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.menu.f_desccolor = GET_COLOR(COLOR_WHITE, bgcurr),
|
||||
.menu.desccolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.menu.f_namecolor = GET_COLOR(COLOR_BLACK, bgcurr),
|
||||
.menu.namecolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.menu.namesepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||
.menu.descsepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||
.menu.f_shortcutcolor = GET_COLOR(COLOR_RED, bgcurr),
|
||||
.menu.shortcutcolor = GET_COLOR(COLOR_RED, bgwidget),
|
||||
.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.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_WHITE, COLOR_BLUE),
|
||||
.bar.color = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
|
||||
.bar.f_color = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
|
||||
.bar.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
|
||||
.button.hmargin = 3,
|
||||
.button.leftdelim = '[',
|
||||
.button.rightdelim = ']',
|
||||
.button.f_delimcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.button.delimcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.button.f_color = GET_COLOR(COLOR_BLACK, bgcurr) | A_UNDERLINE,
|
||||
.button.color = GET_COLOR(COLOR_BLACK, bgwidget) | A_UNDERLINE,
|
||||
.button.f_shortcutcolor = GET_COLOR(COLOR_RED, bgcurr) | A_UNDERLINE,
|
||||
.button.shortcutcolor = GET_COLOR(COLOR_RED, bgwidget) | A_UNDERLINE
|
||||
.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 bsddialog_theme blackwhite = {
|
||||
@ -87,8 +89,8 @@ static struct bsddialog_theme blackwhite = {
|
||||
.screen.color = GET_COLOR(fg, bk),
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.h = 1,
|
||||
.shadow.w = 2,
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = true,
|
||||
.dialog.titlecolor = GET_COLOR(fg, bk),
|
||||
@ -108,15 +110,18 @@ static struct bsddialog_theme blackwhite = {
|
||||
.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),
|
||||
|
||||
.form.f_fieldcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.form.fieldcolor = GET_COLOR(fg, bk),
|
||||
.form.readonlycolor = GET_COLOR(fg, bk),
|
||||
.form.f_fieldcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.form.fieldcolor = GET_COLOR(fg, bk),
|
||||
.form.readonlycolor = GET_COLOR(fg, bk),
|
||||
.form.bottomdesccolor = GET_COLOR(fg, bk),
|
||||
|
||||
.bar.f_color = GET_COLOR(fg, bk) | A_REVERSE,
|
||||
.bar.color = GET_COLOR(fg, bk),
|
||||
|
||||
.button.hmargin = 3,
|
||||
.button.minmargin = 1,
|
||||
.button.maxmargin = 5,
|
||||
.button.leftdelim = '[',
|
||||
.button.rightdelim = ']',
|
||||
.button.f_delimcolor = GET_COLOR(fg, bk),
|
||||
@ -128,11 +133,11 @@ static struct bsddialog_theme blackwhite = {
|
||||
};
|
||||
|
||||
static struct bsddialog_theme dialogtheme = {
|
||||
.screen.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
|
||||
.screen.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
|
||||
|
||||
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||
.shadow.h = 1,
|
||||
.shadow.w = 2,
|
||||
.shadow.y = 1,
|
||||
.shadow.x = 2,
|
||||
|
||||
.dialog.delimtitle = false,
|
||||
.dialog.titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||
@ -140,27 +145,30 @@ static struct bsddialog_theme dialogtheme = {
|
||||
.dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||
.dialog.arrowcolor = GET_COLOR(COLOR_GREEN, COLOR_WHITE),
|
||||
.dialog.arrowcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
|
||||
|
||||
.menu.f_selectorcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
.menu.selectorcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||
.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.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),
|
||||
|
||||
.form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
.form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||
.form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE)| A_BOLD,
|
||||
.form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
.form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||
.form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE)| A_BOLD,
|
||||
.form.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||
|
||||
.bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
.bar.color = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||
|
||||
.button.hmargin = 3,
|
||||
.button.minmargin = 1,
|
||||
.button.maxmargin = 5,
|
||||
.button.leftdelim = '<',
|
||||
.button.rightdelim = '>',
|
||||
.button.f_delimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||
@ -177,8 +185,8 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
|
||||
dst->screen.color = src->screen.color;
|
||||
|
||||
dst->shadow.color = src->shadow.color;
|
||||
dst->shadow.h = src->shadow.h;
|
||||
dst->shadow.w = src->shadow.w;
|
||||
dst->shadow.y = src->shadow.y;
|
||||
dst->shadow.x = src->shadow.x;
|
||||
|
||||
dst->dialog.delimtitle = src->dialog.delimtitle;
|
||||
dst->dialog.titlecolor = src->dialog.titlecolor;
|
||||
@ -198,15 +206,18 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
|
||||
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->form.f_fieldcolor = src->form.f_fieldcolor;
|
||||
dst->form.fieldcolor = src->form.fieldcolor;
|
||||
dst->form.readonlycolor = src->form.readonlycolor;
|
||||
dst->form.f_fieldcolor = src->form.f_fieldcolor;
|
||||
dst->form.fieldcolor = src->form.fieldcolor;
|
||||
dst->form.readonlycolor = src->form.readonlycolor;
|
||||
dst->form.bottomdesccolor = src->form.bottomdesccolor;
|
||||
|
||||
dst->bar.f_color = src->bar.f_color;
|
||||
dst->bar.color = src->bar.color;
|
||||
|
||||
dst->button.hmargin = src->button.hmargin;
|
||||
dst->button.minmargin = src->button.minmargin;
|
||||
dst->button.maxmargin = src->button.maxmargin;
|
||||
dst->button.leftdelim = src->button.leftdelim;
|
||||
dst->button.rightdelim = src->button.rightdelim;
|
||||
dst->button.f_delimcolor = src->button.f_delimcolor;
|
||||
@ -230,7 +241,7 @@ int bsddialog_get_theme(struct bsddialog_theme *theme)
|
||||
|
||||
set_theme(theme, &t);
|
||||
|
||||
return (0);
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_set_theme(struct bsddialog_theme *theme)
|
||||
@ -242,7 +253,7 @@ int bsddialog_set_theme(struct bsddialog_theme *theme)
|
||||
|
||||
set_theme(&t, theme);
|
||||
|
||||
return (0);
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
|
||||
@ -254,6 +265,7 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
|
||||
t.dialog.delimtitle = true;
|
||||
t.button.leftdelim = '[';
|
||||
t.button.rightdelim = ']';
|
||||
t.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE);
|
||||
}
|
||||
else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
|
||||
bsddialog_set_theme(&bsddialogtheme);
|
||||
@ -264,7 +276,7 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
|
||||
else
|
||||
RETURN_ERROR("Unknow default theme");
|
||||
|
||||
return (0);
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int
|
||||
@ -282,3 +294,32 @@ bsddialog_color(enum bsddialog_color foreground,
|
||||
|
||||
return (GET_COLOR(foreground, background) | cursesflags);
|
||||
}
|
||||
|
||||
int
|
||||
bsddialog_color_attrs(int color, enum bsddialog_color *foreground,
|
||||
enum bsddialog_color *background, unsigned int *flags)
|
||||
{
|
||||
unsigned int flag;
|
||||
short f, b;
|
||||
|
||||
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)
|
||||
RETURN_ERROR("Cannot get color attributes");
|
||||
if (foreground != NULL)
|
||||
*foreground = f;
|
||||
if (background != NULL)
|
||||
*background = b;
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
bool bsddialog_hascolors(void)
|
||||
{
|
||||
return hastermcolors;
|
||||
}
|
@ -32,11 +32,42 @@
|
||||
#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 */
|
||||
|
||||
static void
|
||||
drawquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt,
|
||||
const void *value, bool focus)
|
||||
{
|
||||
int h, l, w;
|
||||
|
||||
getmaxyx(win, h, w);
|
||||
draw_borders(conf, win, h, w, 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);
|
||||
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
|
||||
datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
int *w, int minw, const char *text, struct buttons bs)
|
||||
@ -50,7 +81,7 @@ datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
|
||||
}
|
||||
|
||||
if (cols == BSDDIALOG_AUTOSIZE)
|
||||
*w = widget_min_width(conf, htext,minw, &bs);
|
||||
*w = widget_min_width(conf, wtext, minw, &bs);
|
||||
|
||||
if (rows == BSDDIALOG_AUTOSIZE)
|
||||
*h = widget_min_height(conf, htext, 3 /* windows */, true);
|
||||
@ -64,7 +95,7 @@ datetime_checksize(int rows, int cols, int minw, struct buttons bs)
|
||||
int mincols;
|
||||
|
||||
mincols = VBORDERS;
|
||||
mincols += buttons_width(bs);
|
||||
mincols += buttons_min_width(bs);
|
||||
mincols = MAX(minw, mincols);
|
||||
|
||||
if (cols < mincols)
|
||||
@ -81,7 +112,8 @@ 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, input, output, y, x, h, w, sel;
|
||||
int i, retval, y, x, h, w, sel;
|
||||
wint_t input;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
struct buttons bs;
|
||||
struct myclockstruct {
|
||||
@ -131,30 +163,26 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
|
||||
wrefresh(widget);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
mvwprintw(c[i].win, 1, 1, "%2d", c[i].value);
|
||||
wrefresh(c[i].win);
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
drawquare(conf, c[i].win, "%02d", &c[i].value,
|
||||
sel == i);
|
||||
|
||||
if (focusbuttons == false) {
|
||||
wmove(c[sel].win, 1, 2);
|
||||
wrefresh(c[sel].win);
|
||||
}
|
||||
|
||||
input = getch();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
if (focusbuttons == false)
|
||||
break;
|
||||
output = bs.value[bs.curr];
|
||||
loop = false;
|
||||
if (focusbuttons || conf->button.always_active) {
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -165,14 +193,13 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
focusbuttons = bs.curr < (int)bs.nbuttons ?
|
||||
true : false;
|
||||
if (focusbuttons == false) {
|
||||
curs_set(1);
|
||||
sel = 0;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
focusbuttons = sel > 2 ? true : false;
|
||||
if (focusbuttons) {
|
||||
curs_set(0);
|
||||
bs.curr = 0;
|
||||
}
|
||||
}
|
||||
@ -184,25 +211,28 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
bs.curr--;
|
||||
focusbuttons = bs.curr < 0 ? false : true;
|
||||
if (focusbuttons == false) {
|
||||
curs_set(1);
|
||||
sel = 2;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel--;
|
||||
focusbuttons = sel < 0 ? true : false;
|
||||
if (focusbuttons) {
|
||||
curs_set(0);
|
||||
if (focusbuttons)
|
||||
bs.curr = (int)bs.nbuttons - 1;
|
||||
}
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons)
|
||||
break;
|
||||
c[sel].value = c[sel].value > 0 ?
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (focusbuttons)
|
||||
@ -214,10 +244,8 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
curs_set(0);
|
||||
if (f1help(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
curs_set(1);
|
||||
/* No break, screen size can change */
|
||||
case KEY_RESIZE:
|
||||
/* Important for decreasing screen */
|
||||
@ -248,43 +276,33 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
|
||||
|
||||
wclear(c[0].win);
|
||||
mvwin(c[0].win, y + h - 6, x + w/2 - 7);
|
||||
draw_borders(conf, c[0].win, 3, 4, LOWERED);
|
||||
wrefresh(c[0].win);
|
||||
|
||||
wclear(c[1].win);
|
||||
mvwin(c[1].win, y + h - 6, x + w/2 - 2);
|
||||
draw_borders(conf, c[1].win, 3, 4, LOWERED);
|
||||
wrefresh(c[1].win);
|
||||
|
||||
wclear(c[2].win);
|
||||
mvwin(c[2].win, y + h - 6, x + w/2 + 3);
|
||||
draw_borders(conf, c[2].win, 3, 4, LOWERED);
|
||||
wrefresh(c[2].win);
|
||||
|
||||
/* Important to avoid grey lines expanding screen */
|
||||
refresh();
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_OK) {
|
||||
if (retval == BSDDIALOG_OK) {
|
||||
*hh = c[0].value;
|
||||
*mm = c[1].value;
|
||||
*ss = c[2].value;
|
||||
}
|
||||
|
||||
curs_set(0);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
delwin(c[i].win);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
@ -292,7 +310,8 @@ 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, input, output, y, x, h, w, sel;
|
||||
int i, retval, y, x, h, w, sel;
|
||||
wint_t input;
|
||||
WINDOW *widget, *textpad, *shadow;
|
||||
struct buttons bs;
|
||||
struct calendar {
|
||||
@ -363,31 +382,27 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
wrefresh(widget);
|
||||
|
||||
sel = -1;
|
||||
loop = focusbuttons = true;
|
||||
while (loop) {
|
||||
mvwprintw(c[0].win, 1, 1, "%4d", c[0].value);
|
||||
mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name);
|
||||
mvwprintw(c[2].win, 1, 1, "%2d", c[2].value);
|
||||
for (i = 0; i < 3; i++) {
|
||||
wrefresh(c[i].win);
|
||||
}
|
||||
if (focusbuttons == false) {
|
||||
wmove(c[sel].win, 1, c[sel].x);
|
||||
wrefresh(c[sel].win);
|
||||
}
|
||||
drawquare(conf, c[0].win, "%4d", &c[0].value, sel == 0);
|
||||
drawquare(conf, c[1].win, "%9s", m[c[1].value-1].name,
|
||||
sel == 1);
|
||||
drawquare(conf, c[2].win, "%02d", &c[2].value, sel == 2);
|
||||
|
||||
input = getch();
|
||||
if (get_wch(&input) == ERR)
|
||||
continue;
|
||||
switch(input) {
|
||||
case KEY_ENTER:
|
||||
case 10: /* Enter */
|
||||
if (focusbuttons == false)
|
||||
break;
|
||||
output = bs.value[bs.curr];
|
||||
loop = false;
|
||||
if (focusbuttons || conf->button.always_active) {
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
case 27: /* Esc */
|
||||
if (conf->key.enable_esc) {
|
||||
output = BSDDIALOG_ESC;
|
||||
retval = BSDDIALOG_ESC;
|
||||
loop = false;
|
||||
}
|
||||
break;
|
||||
@ -398,14 +413,13 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
focusbuttons = bs.curr < (int)bs.nbuttons ?
|
||||
true : false;
|
||||
if (focusbuttons == false) {
|
||||
curs_set(1);
|
||||
sel = 0;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel++;
|
||||
focusbuttons = sel > 2 ? true : false;
|
||||
if (focusbuttons) {
|
||||
curs_set(0);
|
||||
bs.curr = 0;
|
||||
}
|
||||
}
|
||||
@ -417,33 +431,37 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
bs.curr--;
|
||||
focusbuttons = bs.curr < 0 ? false : true;
|
||||
if (focusbuttons == false) {
|
||||
curs_set(1);
|
||||
sel = 2;
|
||||
bs.curr = conf->button.always_active ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
sel--;
|
||||
focusbuttons = sel < 0 ? true : false;
|
||||
if (focusbuttons) {
|
||||
curs_set(0);
|
||||
if (focusbuttons)
|
||||
bs.curr = (int)bs.nbuttons - 1;
|
||||
}
|
||||
}
|
||||
draw_buttons(widget, bs, true);
|
||||
wrefresh(widget);
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (focusbuttons)
|
||||
break;
|
||||
c[sel].value = c[sel].value > 1 ?
|
||||
c[sel].value - 1 : c[sel].max ;
|
||||
/* if mount change */
|
||||
c[2].max = m[c[1].value -1].days;
|
||||
/* if year change */
|
||||
if (c[1].value == 2 && ISLEAF(c[0].value))
|
||||
c[2].max = 29;
|
||||
/* set new day */
|
||||
if (c[2].value > c[2].max)
|
||||
c[2].value = c[2].max;
|
||||
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 && ISLEAF(c[0].value))
|
||||
c[2].max = 29;
|
||||
/* set new day */
|
||||
if (c[2].value > c[2].max)
|
||||
c[2].value = c[2].max;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (focusbuttons)
|
||||
@ -463,10 +481,8 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
if (conf->key.f1_file == NULL &&
|
||||
conf->key.f1_message == NULL)
|
||||
break;
|
||||
curs_set(0);
|
||||
if (f1help(conf) != 0)
|
||||
return (BSDDIALOG_ERROR);
|
||||
curs_set(1);
|
||||
/* No break, screen size can change */
|
||||
case KEY_RESIZE:
|
||||
/* Important for decreasing screen */
|
||||
@ -496,41 +512,31 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
|
||||
|
||||
wclear(c[0].win);
|
||||
mvwin(c[0].win, y + h - 6, x + w/2 - 11);
|
||||
draw_borders(conf, c[0].win, 3, 6, LOWERED);
|
||||
wrefresh(c[0].win);
|
||||
|
||||
wclear(c[1].win);
|
||||
mvwin(c[1].win, y + h - 6, x + w/2 - 4);
|
||||
draw_borders(conf, c[1].win, 3, 11, LOWERED);
|
||||
wrefresh(c[1].win);
|
||||
|
||||
wclear(c[2].win);
|
||||
mvwin(c[2].win, y + h - 6, x + w/2 + 8);
|
||||
draw_borders(conf, c[2].win, 3, 4, LOWERED);
|
||||
wrefresh(c[2].win);
|
||||
|
||||
/* Important to avoid grey lines expanding screen */
|
||||
refresh();
|
||||
break;
|
||||
default:
|
||||
if (shortcut_buttons(input, &bs)) {
|
||||
output = bs.value[bs.curr];
|
||||
retval = bs.value[bs.curr];
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output == BSDDIALOG_OK) {
|
||||
if (retval == BSDDIALOG_OK) {
|
||||
*yy = c[0].value;
|
||||
*mm = c[1].value;
|
||||
*dd = c[2].value;
|
||||
}
|
||||
|
||||
curs_set(0);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
delwin(c[i].win);
|
||||
end_dialog(conf, shadow, widget, textpad);
|
||||
|
||||
return (output);
|
||||
return (retval);
|
||||
}
|
||||
|
356
contrib/bsddialog/util_theme.c
Normal file
356
contrib/bsddialog/util_theme.c
Normal file
@ -0,0 +1,356 @@
|
||||
/*-
|
||||
* 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 char *color[8] = {
|
||||
"black",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white"
|
||||
};
|
||||
|
||||
int savetheme(const char *file, char *errbuf, 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) {
|
||||
sprintf(errbuf, "Cannot save theme: %s", bsddialog_geterror());
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
if(time(&clock) < 0) {
|
||||
sprintf(errbuf, "Cannot save profile (getting current time)");
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
if ((fp = fopen(file, "w")) == NULL) {
|
||||
sprintf(errbuf, "Cannot open %s to save profile", file);
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int loadtheme(const char *file, char *errbuf)
|
||||
{
|
||||
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) {
|
||||
sprintf(errbuf, "Cannot get current theme: %s",
|
||||
bsddialog_geterror());
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
if((fp = fopen(file, "r")) == NULL) {
|
||||
sprintf(errbuf, "Cannot open theme \"%s\"", file);
|
||||
return (BSDDIALOG_ERROR);
|
||||
}
|
||||
|
||||
#define RETURN_ERROR(name, error) do { \
|
||||
sprintf(errbuf, "%s for \"%s\"", error, name); \
|
||||
fclose(fp); \
|
||||
return (BSDDIALOG_ERROR); \
|
||||
} 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;
|
||||
RETURN_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)
|
||||
RETURN_ERROR(p[i].name, "Cannot get a char");
|
||||
*((int*)p[i].value) = charvalue;
|
||||
break;
|
||||
case INT:
|
||||
if (sscanf(value, "%d", &intvalue) != 1)
|
||||
RETURN_ERROR(p[i].name, "Cannot get a int");
|
||||
*((int*)p[i].value) = intvalue;
|
||||
break;
|
||||
case UINT:
|
||||
if (sscanf(value, "%u", &uintvalue) != 1)
|
||||
RETURN_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)
|
||||
RETURN_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)
|
||||
RETURN_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)
|
||||
RETURN_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);
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
||||
|
||||
int bikeshed(struct bsddialog_conf *conf, char *errbuf)
|
||||
{
|
||||
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)
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
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))
|
||||
return (BSDDIALOG_ERROR);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return (BSDDIALOG_OK);
|
||||
}
|
35
contrib/bsddialog/util_theme.h
Normal file
35
contrib/bsddialog/util_theme.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*-
|
||||
* 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_
|
||||
|
||||
int savetheme(const char *file, char *errbuf, const char *version);
|
||||
int loadtheme(const char *file, char *errbuf);
|
||||
int bikeshed(struct bsddialog_conf *conf, char *errbuf);
|
||||
|
||||
#endif
|
@ -3,7 +3,7 @@ BSDDIALOG= ${SRCTOP}/contrib/bsddialog
|
||||
|
||||
PROG= bsddialog
|
||||
SRCS= bsddialog.c
|
||||
MAN= bsddialog.1
|
||||
MAN= bsddialog.1 util_theme.c
|
||||
CFLAGS+= -I${BSDDIALOG}/lib
|
||||
LIBADD= bsddialog
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user