mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
bsddialog: import snapshot as of 2021-11-24
This commit is contained in:
commit
857c66bb5f
28
GNUMakefile
Normal file
28
GNUMakefile
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||||
|
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
#
|
||||||
|
# Written by Alfonso Sabato Siciliano
|
||||||
|
|
||||||
|
OUTPUT= bsddialog
|
||||||
|
SOURCES= bsddialog.c
|
||||||
|
OBJECTS= $(SOURCES:.c=.o)
|
||||||
|
LIBPATH= ./lib
|
||||||
|
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
|
||||||
|
CFLAGS= -g -Wall -I$(LIBPATH)
|
||||||
|
LDFLAGS= -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
all : $(OUTPUT)
|
||||||
|
|
||||||
|
$(OUTPUT): $(LIBBSDDIALOG) $(OBJECTS)
|
||||||
|
$(CC) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
${LIBBSDDIALOG}:
|
||||||
|
make -C ${LIBPATH} -f GNUMakefile
|
||||||
|
|
||||||
|
%.o: %.c $(LIBBSDDIALOG)
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
make -C ${LIBPATH} -f GNUMakefile clean
|
||||||
|
$(RM) $(OUTPUT) *.o *~
|
24
LICENSE
Normal file
24
LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
BSD 2-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2021, Alfonso Sabato Siciliano
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
|
49
Makefile
Normal file
49
Makefile
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# Any copyright is dedicated to the Public Domain, see:
|
||||||
|
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
#
|
||||||
|
# Written by Alfonso Sabato Siciliano
|
||||||
|
|
||||||
|
OUTPUT= bsddialog
|
||||||
|
SOURCES= bsddialog.c
|
||||||
|
OBJECTS= ${SOURCES:.c=.o}
|
||||||
|
LIBPATH= ${.CURDIR}/lib
|
||||||
|
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
|
||||||
|
|
||||||
|
CFLAGS= -Wall -I${LIBPATH}
|
||||||
|
LDFLAGS= -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
|
||||||
|
|
||||||
|
BINDIR= /usr/local/bin
|
||||||
|
MAN= ${OUTPUT}.1
|
||||||
|
GZIP= gzip -cn
|
||||||
|
MANDIR= /usr/local/share/man/man1
|
||||||
|
|
||||||
|
INSTALL= install
|
||||||
|
RM= rm -f
|
||||||
|
|
||||||
|
all : ${OUTPUT}
|
||||||
|
|
||||||
|
${OUTPUT}: ${LIBBSDDIALOG} ${OBJECTS}
|
||||||
|
${CC} ${LDFLAGS} ${OBJECTS} -o ${.PREFIX}
|
||||||
|
|
||||||
|
${LIBBSDDIALOG}:
|
||||||
|
.if defined(PORTNCURSES)
|
||||||
|
make -C ${LIBPATH} -DPORTNCURSES
|
||||||
|
.else
|
||||||
|
make -C ${LIBPATH}
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||||
|
|
||||||
|
install:
|
||||||
|
${INSTALL} -s -m 555 ${OUTPUT} ${BINDIR}
|
||||||
|
${GZIP} ${MAN} > ${MAN}.gz
|
||||||
|
${INSTALL} -m 444 ${MAN}.gz ${MANDIR}
|
||||||
|
|
||||||
|
unistall:
|
||||||
|
${RM} ${BINDIR}/${OUTPUT}
|
||||||
|
${RM} ${MANDIR}/${MAN}.gz
|
||||||
|
|
||||||
|
clean:
|
||||||
|
make -C ${LIBPATH} clean
|
||||||
|
${RM} ${OUTPUT} *.o *~ *.core ${MAN}.gz
|
160
README.md
Normal file
160
README.md
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
# BSDDialog
|
||||||
|
|
||||||
|
**Work In Progress!**
|
||||||
|
|
||||||
|
This project provides **bsddialog** and **libbsddialog**, an utility and a
|
||||||
|
library to build scripts and tools with *TUI Widgets*.
|
||||||
|
|
||||||
|
Description:
|
||||||
|
<https://www.freebsd.org/status/report-2021-04-2021-06/#_bsddialog_tui_widgets>
|
||||||
|
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
FreeBSD:
|
||||||
|
|
||||||
|
```
|
||||||
|
% git clone https://gitlab.com/alfix/bsddialog.git
|
||||||
|
% cd bsddialog
|
||||||
|
% make
|
||||||
|
% ./bsddialog --msgbox "Hello World!" 8 20
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using XFCE install
|
||||||
|
[devel/ncurses](https://www.freshports.org/devel/ncurses/)
|
||||||
|
|
||||||
|
```
|
||||||
|
% sudo pkg install ncurses
|
||||||
|
% git clone https://gitlab.com/alfix/bsddialog.git
|
||||||
|
% cd bsddialog
|
||||||
|
% make -DPORTNCURSES
|
||||||
|
% ./bsddialog --msgbox "Hello World!" 8 20
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```
|
||||||
|
% git clone https://gitlab.com/alfix/bsddialog.git
|
||||||
|
% cd bsddialog
|
||||||
|
% make -GNUMakefile
|
||||||
|
% ./bsddialog --msgbox "Hello World!" 8 20
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
![screenshot](screenshot.png)
|
||||||
|
|
||||||
|
|
||||||
|
Examples utility:
|
||||||
|
```
|
||||||
|
% ./bsddialog --title msgbox --msgbox "Hello World!" 5 30
|
||||||
|
% ./bsddialog --theme default --title msgbox --msgbox "Hello World!" 5 30
|
||||||
|
% ./bsddialog --begin-y 2 --title yesno --yesno "Hello World!" 5 30
|
||||||
|
% ./bsddialog --ascii-lines --pause "Hello World!" 8 50 5
|
||||||
|
% ./bsddialog --checklist "Space to select" 0 0 0 Name1 Desc1 off Name2 Desc2 on Name3 Desc3 off
|
||||||
|
% ./bsddialog --backtitle "TITLE" --title yesno --hline "bsddialog" --yesno "Hello World!" 5 25
|
||||||
|
% ./bsddialog --extra-button --help-button --defaultno --yesno "Hello World!" 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples library:
|
||||||
|
```
|
||||||
|
% cd library_examples
|
||||||
|
% sh compile
|
||||||
|
% ./buildlist
|
||||||
|
% ./infobox
|
||||||
|
% ./menu
|
||||||
|
% ./mixedlist
|
||||||
|
% ./msgbox
|
||||||
|
% ./ports
|
||||||
|
% ./radiolist
|
||||||
|
% ./theme
|
||||||
|
% ./treeview
|
||||||
|
% ./yesno
|
||||||
|
```
|
||||||
|
|
||||||
|
Use Cases:
|
||||||
|
|
||||||
|
- [portconfig](https://gitlab.com/alfix/portconfig)
|
||||||
|
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
**Common Options:**
|
||||||
|
|
||||||
|
--ascii-lines, --aspect *ratio* (for infobox, msgbox and yesno),
|
||||||
|
--backtitle *backtitle*, --begin-x *x* (--begin *y y*),
|
||||||
|
(--begin *y x*), --cancel-label *string*, -clear (test with multiple widgets),
|
||||||
|
--colors, --date-format *format*, --default-button *string*, --defaultno,
|
||||||
|
--default-item *string*,
|
||||||
|
--exit-label *string*, --extra-button, --extra-label *string*,
|
||||||
|
--hfile *filename* (for completed widgets), n--help-button,
|
||||||
|
--help-label *string*, --help-status, --help-tags, --hline *string*, --ignore,
|
||||||
|
--item-help, --no-cancel, --nocancel, --no-label *string*, --no-items,
|
||||||
|
--no-lines, --no-ok,
|
||||||
|
--nook, --no-shadow, --no-tags, --ok-label *string*, --output-fd *fd*,
|
||||||
|
--output-separator *string*, --print-version,
|
||||||
|
--print-size (todo move lib -> utility), --quoted (quotes all != dialog),
|
||||||
|
--print-maxsize, --shadow, --single-quoted (add --quote-with *ch*?),
|
||||||
|
--separator *string* (alias --output-separator *string*),
|
||||||
|
--separate-output (rename --separate-output-withnl?), --sleep *secs*, --stderr,
|
||||||
|
--stdout, --theme *string* ("bsddialog", "dialog", "blackwhite" and "magenta"),
|
||||||
|
--time-format *format*, --title *title*, --version, --yes-label *string*.
|
||||||
|
|
||||||
|
**Widgets:**
|
||||||
|
|
||||||
|
infobox (do not clear the screen), msgbox,
|
||||||
|
yesno (dialog renames "yes/no" -> "ok/cancel" with --extra-button --help-button).
|
||||||
|
checklist, radiolist, menu, mixedlist, treeview and textbox.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
**Common Options:**
|
||||||
|
|
||||||
|
| Option | Status | Note |
|
||||||
|
| ---------------------------- | ----------- | ------------------------------- |
|
||||||
|
| --cr-wrap | Coding | |
|
||||||
|
| --help | In progress | |
|
||||||
|
| --input-fd *fd* | | |
|
||||||
|
| --insecure | | |
|
||||||
|
| --keep-tite | | |
|
||||||
|
| --keep-window | | |
|
||||||
|
| --last-key | | |
|
||||||
|
| --max-input *size* | | |
|
||||||
|
| --no-collapse | Coding | |
|
||||||
|
| --no-kill | | |
|
||||||
|
| --no-nl-expand | Coding | |
|
||||||
|
| --tab-correct | | |
|
||||||
|
| --tab-len *n* | | |
|
||||||
|
| --trim | Coding | |
|
||||||
|
|
||||||
|
|
||||||
|
To evaluate / Not planned in the short term: --column-separator *string*,
|
||||||
|
--create-rc *file*, --iso-week, --no-mouse, --print-text-only *str h w*,
|
||||||
|
--print-text-size *str h w*, --reorder, -scrollbar, --separate-widget *string*,
|
||||||
|
--size-err, --timeout *secs*,--trace *filename*, --visit-items,
|
||||||
|
--week-start *day*.
|
||||||
|
|
||||||
|
|
||||||
|
**Widgets:**
|
||||||
|
|
||||||
|
| Widget | Status | Note |
|
||||||
|
|--------------- | ----------- | ----------------------------------------------|
|
||||||
|
| --buildlist | In progress | todo autosize, resize, F1 |
|
||||||
|
| --calendar | In progress | todo autosize, resize, F1, leap year, year <=0, month days |
|
||||||
|
| --editbox | | |
|
||||||
|
| --form | In progress | implemented via --mixedform |
|
||||||
|
| --gauge | In progress | |
|
||||||
|
| --inputbox | In progress | implemented via --mixedform, todo \<init\> |
|
||||||
|
| --mixedform | In progress | todo autosize, resize, F1 |
|
||||||
|
| --mixedgauge | In progress | todo autosize, resize, F1 |
|
||||||
|
| --passwordbox | In progress | implemented via --mixedform, todo \<init\> |
|
||||||
|
| --passwordform | In progress | implemented via --mixedform |
|
||||||
|
| --pause | In progress | todo autosize, resize, F1 |
|
||||||
|
| --prgbox | In progress | add command opts |
|
||||||
|
| --programbox | Coding | |
|
||||||
|
| --progressbox | | |
|
||||||
|
| --rangebox | In progress | todo autosize, resize, F1, PAGE-UP/PAGE-DOWN/HOME/END keys |
|
||||||
|
| --timebox | In progress | todo autosize, resize, F1 |
|
||||||
|
|
||||||
|
To evaluate / Not planned in the short term: tailbox (textbox/fseek), tailboxbg,
|
||||||
|
dselect, fselect, inputmenu.
|
1263
bsddialog.c
Normal file
1263
bsddialog.c
Normal file
File diff suppressed because it is too large
Load diff
31
lib/GNUMakefile
Normal file
31
lib/GNUMakefile
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# PUBLIC DOMAIN - NO WARRANTY, see:
|
||||||
|
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
#
|
||||||
|
# Written by Alfonso Sabato Siciliano
|
||||||
|
|
||||||
|
VERSION = 0.1
|
||||||
|
LIBRARY = bsddialog
|
||||||
|
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||||
|
HEADERS = bsddialog.h bsddialog_theme.h
|
||||||
|
SOURCES = barbox.c editorbox.c formbox.c lib_util.c menubox.c textbox.c \
|
||||||
|
timebox.c commandbox.c filebox.c infobox.c libbsddialog.c messagebox.c \
|
||||||
|
theme.c
|
||||||
|
OBJECTS = $(SOURCES:.c=.o)
|
||||||
|
CFLAGS = -g -Wall -Werror -fpic
|
||||||
|
LDFLAGS = -lform -lncurses -ltinfo
|
||||||
|
LIBFLAG = -shared
|
||||||
|
|
||||||
|
RM = rm -f
|
||||||
|
LN = ln -s -f
|
||||||
|
|
||||||
|
all : $(LIBRARY)
|
||||||
|
|
||||||
|
$(LIBRARY): $(OBJECTS)
|
||||||
|
$(CC) $(LIBFLAG) $^ -o $(LIBRARY_SO).$(VERSION) $(LDFLAGS)
|
||||||
|
${LN} ${LIBRARY_SO}.${VERSION} ${LIBRARY_SO}
|
||||||
|
|
||||||
|
%.o: %.c $(HEADERS)
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(LIBRARY_SO)* *.o *~
|
73
lib/Makefile
Normal file
73
lib/Makefile
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# Any copyright is dedicated to the Public Domain, see:
|
||||||
|
# <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
#
|
||||||
|
# Written by Alfonso Sabato Siciliano
|
||||||
|
|
||||||
|
VERSION = 0.1
|
||||||
|
LIBRARY = bsddialog
|
||||||
|
LIBRARY_SO = lib${LIBRARY:=.so}
|
||||||
|
HEADERS = bsddialog.h bsddialog_theme.h
|
||||||
|
SOURCES = barbox.c editorbox.c formbox.c lib_util.c menubox.c textbox.c \
|
||||||
|
timebox.c commandbox.c filebox.c infobox.c libbsddialog.c messagebox.c \
|
||||||
|
theme.c
|
||||||
|
OBJECTS= ${SOURCES:.c=.o}
|
||||||
|
FBSDFLAGS= -O2 -pipe -std=gnu99 -Wno-format-zero-length \
|
||||||
|
-fstack-protector-strong -Qunused-arguments
|
||||||
|
CFLAGS = -I/usr/local/include -fPIC -Wall -Wextra ${FBSDFLAGS}
|
||||||
|
LDFLAGS = -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
|
||||||
|
-Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION}
|
||||||
|
|
||||||
|
INSTALL_PREFIX=/usr/local
|
||||||
|
LN = ln -s -f
|
||||||
|
RM = rm -f
|
||||||
|
CP = cp
|
||||||
|
GZIP = gzip -cn
|
||||||
|
LDCONFIG = /sbin/ldconfig -m
|
||||||
|
|
||||||
|
.if defined(PORTNCURSES)
|
||||||
|
# PORT ncurses `make -DPORTNCURSES` or `make -D PORTNCURSES`
|
||||||
|
CFLAGS += -DPORTNCURSES -I/usr/local/include
|
||||||
|
LDFLAGS += -L/usr/local/lib -lform -lncurses -ltinfo
|
||||||
|
.else
|
||||||
|
# BASE ncurses
|
||||||
|
LDFLAGS += -L/usr/lib -lform -lncurses -ltinfo
|
||||||
|
.endif
|
||||||
|
|
||||||
|
MAN= ${OUTPUT}.3
|
||||||
|
GZIP= gzip -cn
|
||||||
|
MANDIR= /usr/local/share/man/man3
|
||||||
|
|
||||||
|
INSTALL= install
|
||||||
|
RM= rm -f
|
||||||
|
|
||||||
|
#all : man ${LIBRARY}
|
||||||
|
all : ${LIBRARY}
|
||||||
|
|
||||||
|
${LIBRARY}: ${OBJECTS}
|
||||||
|
${CC} ${LDFLAGS} ${.ALLSRC} -o ${LIBRARY_SO}.${VERSION}
|
||||||
|
# LN for devel
|
||||||
|
${LN} ${LIBRARY_SO}.${VERSION} ${LIBRARY_SO}
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||||
|
|
||||||
|
man:
|
||||||
|
${GZIP} ${LIBRARY}.3 > ${LIBRARY}.3.gz
|
||||||
|
|
||||||
|
clean:
|
||||||
|
${RM} ${LIBRARY_SO}* *.o *~ *.gz
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
${CP} ${LIBRARY}.h ${INSTALL_PREFIX}/include
|
||||||
|
${CP} ${LIBRARY_SO}.${VERSION} ${INSTALL_PREFIX}/lib/
|
||||||
|
${LN} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}.${VERSION} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}
|
||||||
|
${LDCONFIG} ${INSTALL_PREFIX}/lib
|
||||||
|
${CP} ${LIBRARY}.3.gz ${INSTALL_PREFIX}/man/man3/
|
||||||
|
|
||||||
|
unistall:
|
||||||
|
${RM} ${INSTALL_PREFIX}/include/${LIBRARY}.h
|
||||||
|
${RM} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}
|
||||||
|
${RM} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}.${VERSION}
|
||||||
|
${LDCONFIG} ${INSTALL_PREFIX}/lib
|
||||||
|
${RM} ${INSTALL_PREFIX}/man/man3/${LIBRARY}.3.gz
|
369
lib/barbox.c
Normal file
369
lib/barbox.c
Normal file
|
@ -0,0 +1,369 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Bar": gauge - mixedgauge - rangebox - pause */
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel, int label)
|
||||||
|
{
|
||||||
|
char labelstr[128];
|
||||||
|
int i, blue_x, color;
|
||||||
|
|
||||||
|
blue_x = (int)((perc*(size))/100);
|
||||||
|
|
||||||
|
wmove(win, y, x);
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
color = (i <= blue_x) ? t.currbarcolor : t.barcolor;
|
||||||
|
wattron(win, color);
|
||||||
|
waddch(win, ' ');
|
||||||
|
wattroff(win, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withlabel)
|
||||||
|
sprintf(labelstr, "%d", label);
|
||||||
|
else
|
||||||
|
sprintf(labelstr, "%3d%%", perc);
|
||||||
|
wmove(win, y, x + size/2 - 2);
|
||||||
|
for (i=0; i < (int) strlen(labelstr); i++) {
|
||||||
|
color = ( (blue_x + 1) <= (size/2 - (int) strlen(labelstr)/2 + i) ) ?
|
||||||
|
t.barcolor : t.currbarcolor;
|
||||||
|
wattron(win, color);
|
||||||
|
waddch(win, labelstr[i]);
|
||||||
|
wattroff(win, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols, int perc)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *bar, *shadow;
|
||||||
|
char input[2048];
|
||||||
|
int i, y, x;
|
||||||
|
bool mainloop = true;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
false) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bar = new_boxed_window(conf, y+rows -4, x+3, 3, cols-6, RAISED);
|
||||||
|
|
||||||
|
wrefresh(widget);
|
||||||
|
wrefresh(bar);
|
||||||
|
|
||||||
|
while (mainloop) {
|
||||||
|
draw_perc_bar(bar, 1, 1, cols-8, perc, false, -1 /*unused*/);
|
||||||
|
|
||||||
|
wrefresh(widget);
|
||||||
|
wrefresh(bar);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
scanf("%s", input);
|
||||||
|
if (strcmp(input,"EOF") == 0) {
|
||||||
|
mainloop = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp(input,"XXX") == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scanf("%d", &perc);
|
||||||
|
perc = perc < 0 ? 0 : perc;
|
||||||
|
perc = perc > 100 ? 100 : perc;
|
||||||
|
i = 2;
|
||||||
|
wmove(widget, 1, 1);
|
||||||
|
wclrtoeol(widget);
|
||||||
|
while (true) {
|
||||||
|
scanf("%s", input);
|
||||||
|
if (strcmp(input,"EOF") == 0) {
|
||||||
|
mainloop = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp(input,"XXX") == 0)
|
||||||
|
break;
|
||||||
|
//print_text(conf, widget, 1, 1, cols-2, input);
|
||||||
|
mvwaddstr(widget, 1, i, input);
|
||||||
|
i = i + strlen(input) + 1;
|
||||||
|
wrefresh(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delwin(bar);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return BSDDIALOG_YESOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_mixedgauge(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int perc, int argc, char **argv)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *bar, *shadow;
|
||||||
|
int i, miniperc, y, x;
|
||||||
|
char states[11][16] = {
|
||||||
|
"[ Succeeded ]",
|
||||||
|
"[ Failed ]",
|
||||||
|
"[ Passed ]",
|
||||||
|
"[ Completed ]",
|
||||||
|
"[ Checked ]",
|
||||||
|
"[ Done ]",
|
||||||
|
"[ Skipped ]",
|
||||||
|
"[ In Progress ]",
|
||||||
|
"!!! BLANK !!!",
|
||||||
|
"[ N/A ]",
|
||||||
|
"[ UNKNOWN ]",};
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, NULL, &rows, &cols, &shadow,
|
||||||
|
false) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bar = new_boxed_window(conf, y+rows -4, x+3, 3, cols-6, RAISED);
|
||||||
|
|
||||||
|
/* mini bars */
|
||||||
|
for (i=0; i < (argc/2); i++) {
|
||||||
|
miniperc = atol(argv[i*2 + 1]);
|
||||||
|
if (miniperc == 8)
|
||||||
|
continue;
|
||||||
|
mvwaddstr(widget, i+1, 2, argv[i*2]);
|
||||||
|
if (miniperc > 9)
|
||||||
|
mvwaddstr(widget, i+1, cols-2-15, states[10]);
|
||||||
|
else if (miniperc >= 0 && miniperc <= 9)
|
||||||
|
mvwaddstr(widget, i+1, cols-2-15, states[miniperc]);
|
||||||
|
else { //miniperc < 0
|
||||||
|
miniperc = abs(miniperc);
|
||||||
|
mvwaddstr(widget, i+1, cols-2-15, "[ ]");
|
||||||
|
draw_perc_bar(widget, i+1, 1+cols-2-15, 13, miniperc,
|
||||||
|
false, -1 /*unused*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_text(conf, widget, rows-6, 2, cols-2, text);
|
||||||
|
|
||||||
|
/* main bar */
|
||||||
|
draw_perc_bar(bar, 1, 1, cols-8, perc, false, -1 /*unused*/);
|
||||||
|
|
||||||
|
wattron(bar, t.barcolor);
|
||||||
|
mvwaddstr(bar, 0, 2, "Overall Progress");
|
||||||
|
wattroff(bar, t.barcolor);
|
||||||
|
|
||||||
|
wrefresh(widget);
|
||||||
|
wrefresh(bar);
|
||||||
|
|
||||||
|
getch();
|
||||||
|
|
||||||
|
delwin(bar);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return BSDDIALOG_YESOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols, int min,
|
||||||
|
int max, int *value)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *bar, *shadow;
|
||||||
|
int y, x;
|
||||||
|
bool loop, buttupdate, barupdate;
|
||||||
|
int input, currvalue, output, sizebar;
|
||||||
|
float perc;
|
||||||
|
int positions = max - min + 1;
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bar = new_boxed_window(conf, y + rows - 6, x +7, 3, cols-14, RAISED);
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
RETURN_ERROR("*value == NULL");
|
||||||
|
|
||||||
|
currvalue = *value;
|
||||||
|
sizebar = cols - 16;
|
||||||
|
loop = buttupdate = barupdate = true;
|
||||||
|
while(loop) {
|
||||||
|
if (barupdate) {
|
||||||
|
perc = ((float)(currvalue - min)*100) / ((float)positions-1);
|
||||||
|
draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue);
|
||||||
|
barupdate = false;
|
||||||
|
wrefresh(bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttupdate) {
|
||||||
|
draw_buttons(widget, rows-2, cols, bs, true);
|
||||||
|
wrefresh(widget);
|
||||||
|
buttupdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = getch();
|
||||||
|
switch(input) {
|
||||||
|
case 10: // Enter
|
||||||
|
output = bs.value[bs.curr]; // values -> outputs
|
||||||
|
*value = currvalue;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': // TAB
|
||||||
|
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||||
|
buttupdate = true;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
if (currvalue < max) {
|
||||||
|
currvalue++;
|
||||||
|
barupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (currvalue > min) {
|
||||||
|
currvalue--;
|
||||||
|
barupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delwin(bar);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols, int sec)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *bar, *shadow;
|
||||||
|
int output, y, x;
|
||||||
|
bool loop, buttupdate, barupdate;
|
||||||
|
int input, currvalue, sizebar;
|
||||||
|
float perc;
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bar = new_boxed_window(conf, y + rows - 6, x +7, 3, cols-14, RAISED);
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
currvalue = sec;
|
||||||
|
sizebar = cols-16;
|
||||||
|
nodelay(stdscr, TRUE);
|
||||||
|
timeout(1000);
|
||||||
|
//wtimeout(buttwin, 2);
|
||||||
|
loop = buttupdate = barupdate = true;
|
||||||
|
while(loop) {
|
||||||
|
if (barupdate) {
|
||||||
|
perc = ((float)(currvalue*100)) / ((float)sec);
|
||||||
|
draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue);
|
||||||
|
barupdate = false;
|
||||||
|
wrefresh(bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttupdate) {
|
||||||
|
draw_buttons(widget, rows-2, cols, bs, true);
|
||||||
|
wrefresh(widget);
|
||||||
|
buttupdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = getch();
|
||||||
|
if(input < 0) {
|
||||||
|
currvalue--;
|
||||||
|
if (currvalue < 0) {
|
||||||
|
output = BSDDIALOG_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
barupdate = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch(input) {
|
||||||
|
case 10: // Enter
|
||||||
|
output = bs.value[bs.curr]; // values -> outputs
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': // TAB
|
||||||
|
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||||
|
buttupdate = true;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodelay(stdscr, FALSE);
|
||||||
|
|
||||||
|
delwin(bar);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
257
lib/bsddialog.h
Normal file
257
lib/bsddialog.h
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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_H_
|
||||||
|
#define _BSDDIALOG_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* Exit status */
|
||||||
|
#define BSDDIALOG_ERROR -1
|
||||||
|
#define BSDDIALOG_YESOK 0
|
||||||
|
#define BSDDIALOG_NOCANCEL 1
|
||||||
|
#define BSDDIALOG_HELP 2
|
||||||
|
#define BSDDIALOG_EXTRA 3
|
||||||
|
#define BSDDIALOG_ITEM_HELP 4
|
||||||
|
#define BSDDIALOG_ESC 5
|
||||||
|
|
||||||
|
/* size and position */
|
||||||
|
#define BSDDIALOG_FULLSCREEN -1
|
||||||
|
#define BSDDIALOG_AUTOSIZE 0
|
||||||
|
#define BSDDIALOG_CENTER -1
|
||||||
|
|
||||||
|
struct bsddialog_conf {
|
||||||
|
/* conf.* */
|
||||||
|
bool ascii_lines;
|
||||||
|
int aspect_ratio;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool clear;
|
||||||
|
int *get_height;
|
||||||
|
int *get_width;
|
||||||
|
char *hfile;
|
||||||
|
char *hline;
|
||||||
|
/*int input_fd;*/
|
||||||
|
/*bool keep_tite;*/
|
||||||
|
/*bool keep_window;*/
|
||||||
|
/*bool last_key;*/
|
||||||
|
/*int max_input;*/
|
||||||
|
/*bool no_kill;*/
|
||||||
|
bool no_lines;
|
||||||
|
/*bool no_mouse; useful?*/
|
||||||
|
/*bool scrollbar; useful?*/
|
||||||
|
/*char *separate_witget;*/
|
||||||
|
bool shadow;
|
||||||
|
/*bool size_err;*/
|
||||||
|
int sleep;
|
||||||
|
/*int timeout;*/
|
||||||
|
char *title;
|
||||||
|
/* conf.text.* */
|
||||||
|
struct {
|
||||||
|
bool colors;
|
||||||
|
bool cr_wrap;
|
||||||
|
bool no_collapse;
|
||||||
|
bool no_nl_expand;
|
||||||
|
/*bool tab_correct; textbox?*/
|
||||||
|
/*int tab_len; textbox?*/
|
||||||
|
bool trim;
|
||||||
|
} text;
|
||||||
|
/* conf.form.* */
|
||||||
|
/*struct {
|
||||||
|
bool insecure;
|
||||||
|
} form;*/
|
||||||
|
/* conf.menu.* */
|
||||||
|
struct {
|
||||||
|
bool align_left;
|
||||||
|
char *colums_separator;
|
||||||
|
char *default_item; /*delete, add int *focus to API?*/
|
||||||
|
bool no_items;
|
||||||
|
bool no_tags;
|
||||||
|
/*bool visit_items;*/
|
||||||
|
} menu;
|
||||||
|
/* conf.button.* */
|
||||||
|
struct {
|
||||||
|
char *cancel_label;
|
||||||
|
bool defaultno;
|
||||||
|
char *default_label;
|
||||||
|
char *exit_label;
|
||||||
|
bool extra_button;
|
||||||
|
char *extra_label;
|
||||||
|
bool help_button;
|
||||||
|
char *help_label;
|
||||||
|
bool no_cancel;
|
||||||
|
char *no_label;
|
||||||
|
bool no_ok;
|
||||||
|
char *ok_label;
|
||||||
|
char *yes_label;
|
||||||
|
} button;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bsddialog_menuitem {
|
||||||
|
char *prefix;
|
||||||
|
bool on;
|
||||||
|
int depth;
|
||||||
|
char *name;
|
||||||
|
char *desc;
|
||||||
|
char *bottomdesc;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bsddialog_grouptype {
|
||||||
|
BSDDIALOG_CHECKLIST,
|
||||||
|
BSDDIALOG_RADIOLIST,
|
||||||
|
BSDDIALOG_SEPARATOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bsddialog_menugroup {
|
||||||
|
enum bsddialog_grouptype type;
|
||||||
|
unsigned int nitems;
|
||||||
|
struct bsddialog_menuitem *items;
|
||||||
|
};
|
||||||
|
|
||||||
|
int bsddialog_init(void);
|
||||||
|
int bsddialog_end(void);
|
||||||
|
int bsddialog_backtitle(struct bsddialog_conf conf, char *backtitle);
|
||||||
|
const char *bsddialog_geterror(void);
|
||||||
|
int bsddialog_terminalheight(void);
|
||||||
|
int bsddialog_terminalwidth(void);
|
||||||
|
void bsddialog_initconf(struct bsddialog_conf *conf);
|
||||||
|
|
||||||
|
/* widgets */
|
||||||
|
int
|
||||||
|
bsddialog_buildlist(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
|
||||||
|
int *focusitem);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int *yy, unsigned int *mm, unsigned int *dd);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_checklist(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
|
||||||
|
int *focusitem);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_dselect(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_editbox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int bsddialog_form(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int argc, char **argv);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_fselect(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_gauge(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int perc);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_infobox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_inputbox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_inputmenu(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_menu(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
|
||||||
|
int *focusitem);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int argc, char **argv);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_mixedgauge(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int perc, int argc, char **argv);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_mixedlist(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups,
|
||||||
|
int *focuslist, int *focusitem);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_msgbox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_passwordbox(struct bsddialog_conf conf, char* text, int rows,
|
||||||
|
int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_passwordform(struct bsddialog_conf conf, char* text, int rows,
|
||||||
|
int cols, int formheight, int argc, char **argv);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_pause(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int sec);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_prgbox(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
char *command);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_programbox(struct bsddialog_conf conf, char* text, int rows,
|
||||||
|
int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_progressbox(struct bsddialog_conf conf, char* text, int rows,
|
||||||
|
int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_radiolist(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
|
||||||
|
int *focusitem);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_rangebox(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int min, int max, int *value);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_tailbox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_tailboxbg(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_textbox(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int *hh, unsigned int *mm, unsigned int *ss);
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_treeview(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
|
||||||
|
int *focusitem);
|
||||||
|
|
||||||
|
int bsddialog_yesno(struct bsddialog_conf conf, char* text, int rows, int cols);
|
||||||
|
|
||||||
|
#endif
|
96
lib/bsddialog_theme.h
Normal file
96
lib/bsddialog_theme.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 _LIBBSDDIALOG_THEME_H_
|
||||||
|
#define _LIBBSDDIALOG_THEME_H_
|
||||||
|
|
||||||
|
enum bsddialog_color {
|
||||||
|
BSDDIALOG_BLACK = 0,
|
||||||
|
BSDDIALOG_RED,
|
||||||
|
BSDDIALOG_GREEN,
|
||||||
|
BSDDIALOG_YELLOW,
|
||||||
|
BSDDIALOG_BLUE,
|
||||||
|
BSDDIALOG_MAGENTA,
|
||||||
|
BSDDIALOG_CYAN,
|
||||||
|
BSDDIALOG_WHITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bsddialog_theme {
|
||||||
|
int shadowcolor;
|
||||||
|
unsigned int shadowrows;
|
||||||
|
unsigned int shadowcols;
|
||||||
|
|
||||||
|
int backgroundcolor;
|
||||||
|
bool surroundtitle;
|
||||||
|
int titlecolor;
|
||||||
|
int lineraisecolor;
|
||||||
|
int linelowercolor;
|
||||||
|
int widgetcolor;
|
||||||
|
|
||||||
|
unsigned int texthmargin;
|
||||||
|
|
||||||
|
int curritemcolor;
|
||||||
|
int itemcolor;
|
||||||
|
int currtagcolor;
|
||||||
|
int tagcolor;
|
||||||
|
int namesepcolor;
|
||||||
|
int descsepcolor;
|
||||||
|
|
||||||
|
int currfieldcolor;
|
||||||
|
int fieldcolor;
|
||||||
|
int fieldreadonlycolor;
|
||||||
|
|
||||||
|
int currbarcolor;
|
||||||
|
int barcolor;
|
||||||
|
|
||||||
|
unsigned int buttonspace;
|
||||||
|
int buttleftch;
|
||||||
|
int buttrightchar;
|
||||||
|
int currbuttdelimcolor;
|
||||||
|
int buttdelimcolor;
|
||||||
|
int currbuttoncolor;
|
||||||
|
int buttoncolor;
|
||||||
|
int currshortkeycolor;
|
||||||
|
int shortkeycolor;
|
||||||
|
|
||||||
|
int bottomtitlecolor;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bsddialog_default_theme {
|
||||||
|
BSDDIALOG_THEME_BLACKWHITE,
|
||||||
|
BSDDIALOG_THEME_BSDDIALOG,
|
||||||
|
BSDDIALOG_THEME_DEFAULT,
|
||||||
|
BSDDIALOG_THEME_DIALOG,
|
||||||
|
BSDDIALOG_THEME_MAGENTA,
|
||||||
|
};
|
||||||
|
|
||||||
|
int bsddialog_color(enum bsddialog_color background, enum bsddialog_color foreground);
|
||||||
|
struct bsddialog_theme bsddialog_get_theme();
|
||||||
|
void bsddialog_set_theme(struct bsddialog_theme theme);
|
||||||
|
int bsddialog_set_default_theme(enum bsddialog_default_theme theme);
|
||||||
|
|
||||||
|
#endif
|
211
lib/commandbox.c
Normal file
211
lib/commandbox.c
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 <unistd.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Command": prgbox - programbox - progressbox */
|
||||||
|
|
||||||
|
#define MAXINPUT 2048 /* in bsddialoh.h? in bsddialog.c get/set static maxinput? */
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
command_handler(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey)
|
||||||
|
{
|
||||||
|
bool loop, update;
|
||||||
|
int i, input;
|
||||||
|
int output;
|
||||||
|
|
||||||
|
loop = update = true;
|
||||||
|
while(loop) {
|
||||||
|
if (update) {
|
||||||
|
draw_buttons(window, y, cols, bs, shortkey);
|
||||||
|
update = false;
|
||||||
|
}
|
||||||
|
wrefresh(window);
|
||||||
|
input = getch();
|
||||||
|
switch (input) {
|
||||||
|
case 10: /* Enter */
|
||||||
|
output = bs.value[bs.curr];
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': /* TAB */
|
||||||
|
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||||
|
update = true;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (shortkey) {
|
||||||
|
for (i = 0; i < (int) bs.nbuttons; i++)
|
||||||
|
if (input == (bs.label[i])[0]) {
|
||||||
|
output = bs.value[i];
|
||||||
|
loop = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_prgbox(struct bsddialog_conf conf, char* text, int rows, int cols, char *command)
|
||||||
|
{
|
||||||
|
char line[MAXINPUT];
|
||||||
|
WINDOW *widget, *pad, *shadow;
|
||||||
|
int i, y, x, padrows, padcols, ys, ye, xs, xe;
|
||||||
|
int output;
|
||||||
|
int pipefd[2];
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
NULL, BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
if (text != NULL && conf.no_lines == false) {
|
||||||
|
print_text(conf, widget, 1, 1, cols-2, text);
|
||||||
|
mvwhline(widget, 2, 2, conf.ascii_lines ? '-' : ACS_HLINE, cols -4);
|
||||||
|
wrefresh(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
padrows = text == NULL ? rows - 4 : rows - 6;
|
||||||
|
padcols = cols - 2;
|
||||||
|
ys = text == NULL ? y + 1 : y + 3;
|
||||||
|
xs = x + 1;
|
||||||
|
ye = ys + padrows;
|
||||||
|
xe = xs + padcols;
|
||||||
|
|
||||||
|
pad = newpad(padrows, padcols);
|
||||||
|
wbkgd(pad, t.widgetcolor);
|
||||||
|
|
||||||
|
pipe(pipefd);
|
||||||
|
if (fork() == 0)
|
||||||
|
{
|
||||||
|
close(pipefd[0]); // close reading
|
||||||
|
|
||||||
|
dup2(pipefd[1], 1); // send stdout to the pipe
|
||||||
|
dup2(pipefd[1], 2); // send stderr to the pipe
|
||||||
|
|
||||||
|
close(pipefd[1]); // this descriptor is no longer needed
|
||||||
|
|
||||||
|
//const char *ls="/bin/ls";
|
||||||
|
execl(command, command, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close(pipefd[1]); // close write
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (read(pipefd[0], line, MAXINPUT) != 0) {
|
||||||
|
mvwaddstr(pad, i, 0, line);
|
||||||
|
prefresh(pad, 0, 0, ys, xs, ye, xe);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output = command_handler(widget, rows-2, cols, bs, true);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_programbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
char line[MAXINPUT];
|
||||||
|
WINDOW *widget, *pad, *shadow;
|
||||||
|
int i, y, x, padrows, padcols, ys, ye, xs, xe, output;
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
if (text != NULL && conf.no_lines == false) {
|
||||||
|
mvwhline(widget, 2, 2, conf.ascii_lines ? '-' : ACS_HLINE, cols -4);
|
||||||
|
wrefresh(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
padrows = text == NULL ? rows - 4 : rows - 6;
|
||||||
|
padcols = cols - 2;
|
||||||
|
ys = text == NULL ? y + 1 : y + 3;
|
||||||
|
xs = x + 1;
|
||||||
|
ye = ys + padrows;
|
||||||
|
xe = xs + padcols;
|
||||||
|
|
||||||
|
pad = newpad(padrows, padcols);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
//while (fgets(line, MAXINPUT, stdin) != NULL) {
|
||||||
|
while(getstr(line) != ERR){
|
||||||
|
mvwaddstr(pad, i, 0, line);
|
||||||
|
prefresh(pad, 0, 0, ys, xs, ye, xe);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
output = command_handler(widget, rows-2, cols, bs, true);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_progressbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
text = "Progressbox unimplemented";
|
||||||
|
bsddialog_msgbox(conf, text, rows, cols);
|
||||||
|
RETURN_ERROR(text);
|
||||||
|
}
|
||||||
|
|
45
lib/editorbox.c
Normal file
45
lib/editorbox.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
|
||||||
|
/* "Editor": editbox */
|
||||||
|
|
||||||
|
int bsddialog_editbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
text = "Editbox unimplemented";
|
||||||
|
bsddialog_msgbox(conf, text, rows, cols);
|
||||||
|
RETURN_ERROR(text);
|
||||||
|
}
|
||||||
|
|
52
lib/filebox.c
Normal file
52
lib/filebox.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
|
||||||
|
/* "File": dselect - fselect */
|
||||||
|
|
||||||
|
int bsddialog_dselect(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
text = "Dselect unimplemented";
|
||||||
|
bsddialog_msgbox(conf, text, rows, cols);
|
||||||
|
RETURN_ERROR(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_fselect(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
text = "Fselect unimplemented";
|
||||||
|
bsddialog_msgbox(conf, text, rows, cols);
|
||||||
|
RETURN_ERROR(text);
|
||||||
|
}
|
||||||
|
|
396
lib/formbox.c
Normal file
396
lib/formbox.c
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#include <ncurses/form.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#include <form.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Form": inputbox - passwordbox - form - passwordform - mixedform */
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
int bsddialog_inputmenu(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
text = "Inputbox unimplemented";
|
||||||
|
bsddialog_msgbox(conf, text, rows, cols);
|
||||||
|
RETURN_ERROR(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ITEMHIDDEN 0x1
|
||||||
|
#define ISITEMHIDDEN(item) (item.itemflags & 0x1)
|
||||||
|
#define ITEMREADONLY 0x2
|
||||||
|
#define ISITEMREADONLY(item) (item.itemflags & 0x2)
|
||||||
|
struct formitem {
|
||||||
|
char *label;
|
||||||
|
unsigned int ylabel;
|
||||||
|
unsigned int xlabel;
|
||||||
|
char *item;
|
||||||
|
unsigned int yitem;
|
||||||
|
unsigned int xitem;
|
||||||
|
int itemlen;
|
||||||
|
unsigned int inputlen;
|
||||||
|
unsigned int itemflags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
mixedform_handler(WINDOW *widget, int y, int cols, struct buttons bs,
|
||||||
|
bool shortkey, WINDOW *entry, FORM *form, FIELD **field, int nitems
|
||||||
|
/*struct formitem *items*/)
|
||||||
|
{
|
||||||
|
bool loop, buttupdate, inentry = true;
|
||||||
|
int input, output;
|
||||||
|
|
||||||
|
curs_set(2);
|
||||||
|
pos_form_cursor(form);
|
||||||
|
loop = buttupdate = true;
|
||||||
|
bs.curr = -1;
|
||||||
|
while(loop) {
|
||||||
|
if (buttupdate) {
|
||||||
|
draw_buttons(widget, y, cols, bs, shortkey);
|
||||||
|
wrefresh(widget);
|
||||||
|
buttupdate = false;
|
||||||
|
}
|
||||||
|
wrefresh(entry);
|
||||||
|
input = getch();
|
||||||
|
switch(input) {
|
||||||
|
case 10: // Enter
|
||||||
|
if (inentry)
|
||||||
|
break;
|
||||||
|
output = bs.value[bs.curr]; // values -> buttvalues
|
||||||
|
form_driver(form, REQ_NEXT_FIELD);
|
||||||
|
form_driver(form, REQ_PREV_FIELD);
|
||||||
|
/* add a struct for forms */
|
||||||
|
/*for (i=0; i<nitems; i++) {
|
||||||
|
bufp = field_buffer(field[i], 0);
|
||||||
|
dprintf(fd, "\n+%s", bufp);
|
||||||
|
bufp = field_buffer(field[i], 1);
|
||||||
|
dprintf(fd, "-%s+", bufp);
|
||||||
|
}*/
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': // TAB
|
||||||
|
if (inentry) {
|
||||||
|
bs.curr = 0;
|
||||||
|
inentry = false;
|
||||||
|
curs_set(0);
|
||||||
|
} else {
|
||||||
|
bs.curr++;
|
||||||
|
inentry = bs.curr >= (int) bs.nbuttons ? true : false;
|
||||||
|
if (inentry) {
|
||||||
|
curs_set(2);
|
||||||
|
pos_form_cursor(form);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buttupdate = true;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (inentry) {
|
||||||
|
form_driver(form, REQ_PREV_CHAR);
|
||||||
|
} else {
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (inentry) {
|
||||||
|
form_driver(form, REQ_NEXT_CHAR);
|
||||||
|
} else {
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
if (nitems < 2)
|
||||||
|
break;
|
||||||
|
set_field_fore(current_field(form), t.fieldcolor);
|
||||||
|
set_field_back(current_field(form), t.fieldcolor);
|
||||||
|
form_driver(form, REQ_PREV_FIELD);
|
||||||
|
form_driver(form, REQ_END_LINE);
|
||||||
|
set_field_fore(current_field(form), t.currfieldcolor);
|
||||||
|
set_field_back(current_field(form), t.currfieldcolor);
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (nitems < 2)
|
||||||
|
break;
|
||||||
|
set_field_fore(current_field(form), t.fieldcolor);
|
||||||
|
set_field_back(current_field(form), t.fieldcolor);
|
||||||
|
form_driver(form, REQ_NEXT_FIELD);
|
||||||
|
form_driver(form, REQ_END_LINE);
|
||||||
|
set_field_fore(current_field(form), t.currfieldcolor);
|
||||||
|
set_field_back(current_field(form), t.currfieldcolor);
|
||||||
|
break;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
form_driver(form, REQ_DEL_PREV);
|
||||||
|
break;
|
||||||
|
case KEY_DC:
|
||||||
|
form_driver(form, REQ_DEL_CHAR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (inentry) {
|
||||||
|
form_driver(form, input);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curs_set(0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int nitems, struct formitem *items)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *entry, *shadow;
|
||||||
|
int i, output, color, y, x;
|
||||||
|
FIELD **field;
|
||||||
|
FORM *form;
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
entry = new_boxed_window(conf, y + rows - 3 - formheight -2, x +1,
|
||||||
|
formheight+2, cols-2, LOWERED);
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
field = calloc(nitems + 1, sizeof(FIELD*));
|
||||||
|
for (i=0; i < nitems; i++) {
|
||||||
|
field[i] = new_field(1, items[i].itemlen, items[i].yitem-1, items[i].xitem-1, 0, 1);
|
||||||
|
field_opts_off(field[i], O_STATIC);
|
||||||
|
set_max_field(field[i], items[i].inputlen);
|
||||||
|
set_field_buffer(field[i], 0, items[i].item);
|
||||||
|
set_field_buffer(field[i], 1, items[i].item);
|
||||||
|
field_opts_off(field[i], O_AUTOSKIP);
|
||||||
|
field_opts_off(field[i], O_BLANK);
|
||||||
|
//field_opts_off(field[i], O_BS_OVERLOAD);
|
||||||
|
|
||||||
|
if (ISITEMHIDDEN(items[i]))
|
||||||
|
field_opts_off(field[i], O_PUBLIC);
|
||||||
|
|
||||||
|
if (ISITEMREADONLY(items[i])) {
|
||||||
|
field_opts_off(field[i], O_EDIT);
|
||||||
|
field_opts_off(field[i], O_ACTIVE);
|
||||||
|
color = t.fieldreadonlycolor;
|
||||||
|
} else {
|
||||||
|
color = i == 0 ? t.currfieldcolor : t.fieldcolor;
|
||||||
|
}
|
||||||
|
set_field_fore(field[i], color);
|
||||||
|
set_field_back(field[i], color);
|
||||||
|
}
|
||||||
|
field[i] = NULL;
|
||||||
|
|
||||||
|
if (nitems == 1) {// inputbox or passwordbox
|
||||||
|
set_field_fore(field[0], t.widgetcolor);
|
||||||
|
set_field_back(field[0], t.widgetcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
form = new_form(field);
|
||||||
|
set_form_win(form, entry);
|
||||||
|
set_form_sub(form, derwin(entry, nitems, cols-4, 1, 1));
|
||||||
|
post_form(form);
|
||||||
|
|
||||||
|
for (i=0; i < nitems; i++)
|
||||||
|
mvwaddstr(entry, items[i].ylabel, items[i].xlabel, items[i].label);
|
||||||
|
|
||||||
|
wrefresh(entry);
|
||||||
|
|
||||||
|
output = mixedform_handler(widget, rows-2, cols, bs, true, entry, form,
|
||||||
|
field, nitems /*,items*/);
|
||||||
|
|
||||||
|
unpost_form(form);
|
||||||
|
free_form(form);
|
||||||
|
for (i=0; i < nitems; i++)
|
||||||
|
free_field(field[i]);
|
||||||
|
free(field);
|
||||||
|
|
||||||
|
delwin(entry);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_inputbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
struct formitem item;
|
||||||
|
|
||||||
|
item.label = "";
|
||||||
|
item.ylabel = 0;
|
||||||
|
item.xlabel = 0;
|
||||||
|
item.item = ""; // TODO add argv
|
||||||
|
item.yitem = 1;
|
||||||
|
item.xitem = 1;
|
||||||
|
item.itemlen = cols-4;
|
||||||
|
item.inputlen = 2048; // todo conf.sizeinput
|
||||||
|
item.itemflags = 0;
|
||||||
|
|
||||||
|
output = do_mixedform(conf, text, rows, cols, 1, 1, &item);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_passwordbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
struct formitem item;
|
||||||
|
|
||||||
|
item.label = "";
|
||||||
|
item.ylabel = 0;
|
||||||
|
item.xlabel = 0;
|
||||||
|
item.item = ""; // TODO add argv
|
||||||
|
item.yitem = 1;
|
||||||
|
item.xitem = 1;
|
||||||
|
item.itemlen = cols-4;
|
||||||
|
item.inputlen = 2048; // todo conf.sizeinput
|
||||||
|
item.itemflags = ITEMHIDDEN;
|
||||||
|
|
||||||
|
output = do_mixedform(conf, text, rows, cols, 1, 1, &item);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_mixedform(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, output, nitems;
|
||||||
|
struct formitem items[128];
|
||||||
|
|
||||||
|
if ((argc % 9) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
nitems = argc / 9;
|
||||||
|
for (i=0; i<nitems; i++) {
|
||||||
|
items[i].label = argv[9*i];
|
||||||
|
items[i].ylabel = atoi(argv[9*i+1]);
|
||||||
|
items[i].xlabel = atoi(argv[9*i+2]);
|
||||||
|
items[i].item = argv[9*i+3];
|
||||||
|
items[i].yitem = atoi(argv[9*i+4]);
|
||||||
|
items[i].xitem = atoi(argv[9*i+5]);
|
||||||
|
items[i].itemlen = atoi(argv[9*i+6]);
|
||||||
|
items[i].inputlen = atoi(argv[9*i+7]);
|
||||||
|
items[i].itemflags = atoi(argv[9*i+8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
output = do_mixedform(conf, text, rows, cols, formheight, nitems, items);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_form(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, output, nitems, itemlen, inputlen;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
struct formitem items[128];
|
||||||
|
|
||||||
|
if ((argc % 8) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
nitems = argc / 8;
|
||||||
|
for (i=0; i<nitems; i++) {
|
||||||
|
items[i].label = argv[8*i];
|
||||||
|
items[i].ylabel = atoi(argv[8*i+1]);
|
||||||
|
items[i].xlabel = atoi(argv[8*i+2]);
|
||||||
|
items[i].item = argv[8*i+3];
|
||||||
|
items[i].yitem = atoi(argv[8*i+4]);
|
||||||
|
items[i].xitem = atoi(argv[8*i+5]);
|
||||||
|
|
||||||
|
itemlen = atoi(argv[8*i+6]);
|
||||||
|
items[i].itemlen = abs(itemlen);
|
||||||
|
|
||||||
|
inputlen = atoi(argv[8*i+7]);
|
||||||
|
items[i].inputlen = inputlen == 0 ? abs(itemlen) : inputlen;
|
||||||
|
|
||||||
|
flags = flags | (itemlen < 0 ? ITEMREADONLY : 0);
|
||||||
|
items[i].itemflags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
output = do_mixedform(conf, text, rows, cols, formheight, nitems, items);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_passwordform(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
int formheight, int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, output, nitems, itemlen, inputlen;
|
||||||
|
unsigned int flags = ITEMHIDDEN;
|
||||||
|
struct formitem items[128];
|
||||||
|
|
||||||
|
if ((argc % 8) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
nitems = argc / 8;
|
||||||
|
for (i=0; i<nitems; i++) {
|
||||||
|
items[i].label = argv[8*i];
|
||||||
|
items[i].ylabel = atoi(argv[8*i+1]);
|
||||||
|
items[i].xlabel = atoi(argv[8*i+2]);
|
||||||
|
items[i].item = argv[8*i+3];
|
||||||
|
items[i].yitem = atoi(argv[8*i+4]);
|
||||||
|
items[i].xitem = atoi(argv[8*i+5]);
|
||||||
|
|
||||||
|
itemlen = atoi(argv[8*i+6]);
|
||||||
|
items[i].itemlen = abs(itemlen);
|
||||||
|
|
||||||
|
inputlen = atoi(argv[8*i+7]);
|
||||||
|
items[i].inputlen = inputlen == 0 ? abs(itemlen) : inputlen;
|
||||||
|
|
||||||
|
flags = flags | (itemlen < 0 ? ITEMREADONLY : 0);
|
||||||
|
items[i].itemflags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
output = do_mixedform(conf, text, rows, cols, formheight, nitems, items);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
114
lib/infobox.c
Normal file
114
lib/infobox.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Alfonso Sabato Siciliano
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Info": infobox */
|
||||||
|
|
||||||
|
#define MIN_HEIGHT 3
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
infobox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w,
|
||||||
|
char *text)
|
||||||
|
{
|
||||||
|
int maxword, maxline, nlines;
|
||||||
|
|
||||||
|
if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (cols == BSDDIALOG_AUTOSIZE) {
|
||||||
|
/* text size */
|
||||||
|
*w = maxline + VBORDERS + t.texthmargin * 2;
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*w = MIN(*w, widget_max_width(conf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows == BSDDIALOG_AUTOSIZE) {
|
||||||
|
*h = MIN_HEIGHT - 1;
|
||||||
|
if (maxword > 0)
|
||||||
|
*h += MIN(nlines, (*w / GET_ASPECT_RATIO(conf)));
|
||||||
|
*h = MAX(*h, MIN_HEIGHT);
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*h = MIN(*h, widget_max_height(conf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int infobox_checksize(int rows, int cols)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (cols < HBORDERS + 1 + (int) t.texthmargin * 2)
|
||||||
|
RETURN_ERROR("Few cols, infobox needs at least width 3 + text "\
|
||||||
|
"margins");
|
||||||
|
|
||||||
|
if (rows < 3)
|
||||||
|
RETURN_ERROR("Infobox needs at least height 3");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_infobox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
WINDOW *shadow, *widget, *textpad;
|
||||||
|
int y, x, h, w, htextpad;
|
||||||
|
|
||||||
|
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (infobox_autosize(conf, rows, cols, &h, &w, text) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (infobox_checksize(h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
|
||||||
|
&textpad, &htextpad, text, false) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
pnoutrefresh(textpad, 0, 0, y+1, x+1+t.texthmargin, y+h-2, x+w-t.texthmargin);
|
||||||
|
|
||||||
|
doupdate();
|
||||||
|
|
||||||
|
end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
|
||||||
|
|
||||||
|
return (BSDDIALOG_YESOK);
|
||||||
|
}
|
||||||
|
|
996
lib/lib_util.c
Normal file
996
lib/lib_util.c
Normal file
|
@ -0,0 +1,996 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Alfonso Sabato Siciliano
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
/* Error buffer */
|
||||||
|
|
||||||
|
#define ERRBUFLEN 1024
|
||||||
|
static char errorbuffer[ERRBUFLEN];
|
||||||
|
|
||||||
|
const char *get_error_string(void)
|
||||||
|
{
|
||||||
|
return errorbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_error_string(char *str)
|
||||||
|
{
|
||||||
|
|
||||||
|
strncpy(errorbuffer, str, ERRBUFLEN-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleaner */
|
||||||
|
int hide_widget(int y, int x, int h, int w, bool withshadow)
|
||||||
|
{
|
||||||
|
WINDOW *clear;
|
||||||
|
|
||||||
|
/* no check: y, x, h and w are checked by the builders */
|
||||||
|
if ((clear = newwin(h, w, y + t.shadowrows, x + t.shadowcols)) == NULL)
|
||||||
|
RETURN_ERROR("Cannot hide the widget");
|
||||||
|
wbkgd(clear, t.backgroundcolor);
|
||||||
|
|
||||||
|
if (withshadow)
|
||||||
|
wrefresh(clear);
|
||||||
|
|
||||||
|
mvwin(clear, y, x);
|
||||||
|
wrefresh(clear);
|
||||||
|
|
||||||
|
delwin(clear);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* F1 help */
|
||||||
|
int f1help(struct bsddialog_conf conf)
|
||||||
|
{
|
||||||
|
char *file = conf.hfile;
|
||||||
|
char *title = conf.title;
|
||||||
|
int output;
|
||||||
|
|
||||||
|
conf.hfile = NULL;
|
||||||
|
conf.clear = true;
|
||||||
|
conf.y = BSDDIALOG_CENTER;
|
||||||
|
conf.x = BSDDIALOG_CENTER;
|
||||||
|
conf.title = "HELP";
|
||||||
|
conf.sleep = 0;
|
||||||
|
|
||||||
|
output = bsddialog_textbox(conf, file, BSDDIALOG_AUTOSIZE,
|
||||||
|
BSDDIALOG_AUTOSIZE);
|
||||||
|
conf.hfile = file;
|
||||||
|
conf.title = title;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
void
|
||||||
|
draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
|
||||||
|
bool shortkey)
|
||||||
|
{
|
||||||
|
int i, color_arrows, color_shortkey, color_button;
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
color_arrows = t.currbuttdelimcolor;
|
||||||
|
color_shortkey = t.currshortkeycolor;
|
||||||
|
color_button = t.currbuttoncolor;
|
||||||
|
} else {
|
||||||
|
color_arrows = t.buttdelimcolor;
|
||||||
|
color_shortkey = t.shortkeycolor;
|
||||||
|
color_button = t.buttoncolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
wattron(window, color_arrows);
|
||||||
|
mvwaddch(window, y, x, t.buttleftch);
|
||||||
|
wattroff(window, color_arrows);
|
||||||
|
wattron(window, color_button);
|
||||||
|
for(i = 1; i < size - 1; i++)
|
||||||
|
waddch(window, ' ');
|
||||||
|
wattroff(window, color_button);
|
||||||
|
wattron(window, color_arrows);
|
||||||
|
mvwaddch(window, y, x + i, t.buttrightchar);
|
||||||
|
wattroff(window, color_arrows);
|
||||||
|
|
||||||
|
x = x + 1 + ((size - 2 - strlen(text))/2);
|
||||||
|
wattron(window, color_button);
|
||||||
|
mvwaddstr(window, y, x, text);
|
||||||
|
wattroff(window, color_button);
|
||||||
|
|
||||||
|
if (shortkey) {
|
||||||
|
wattron(window, color_shortkey);
|
||||||
|
mvwaddch(window, y, x, text[0]);
|
||||||
|
wattroff(window, color_shortkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey)
|
||||||
|
{
|
||||||
|
int i, x, start_x;
|
||||||
|
|
||||||
|
start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.buttonspace;
|
||||||
|
start_x = cols/2 - start_x/2;
|
||||||
|
|
||||||
|
for (i = 0; i < (int) bs.nbuttons; i++) {
|
||||||
|
x = i * (bs.sizebutton + t.buttonspace);
|
||||||
|
draw_button(window, y, start_x + x, bs.sizebutton, bs.label[i],
|
||||||
|
i == bs.curr, shortkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel,
|
||||||
|
char *extralabel, char *nocancellabel, char *helplabel)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
#define SIZEBUTTON 8
|
||||||
|
#define DEFAULT_BUTTON_LABEL LABEL_ok_label
|
||||||
|
#define DEFAULT_BUTTON_VALUE BSDDIALOG_YESOK
|
||||||
|
|
||||||
|
|
||||||
|
bs->nbuttons = 0;
|
||||||
|
bs->curr = 0;
|
||||||
|
bs->sizebutton = 0;
|
||||||
|
|
||||||
|
if (yesoklabel != NULL && conf.button.no_ok == false) {
|
||||||
|
bs->label[0] = yesoklabel;
|
||||||
|
bs->value[0] = BSDDIALOG_YESOK;
|
||||||
|
bs->nbuttons += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extralabel != NULL && conf.button.extra_button) {
|
||||||
|
bs->label[bs->nbuttons] = extralabel;
|
||||||
|
bs->value[bs->nbuttons] = BSDDIALOG_EXTRA;
|
||||||
|
bs->nbuttons += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nocancellabel != NULL && conf.button.no_cancel == false) {
|
||||||
|
bs->label[bs->nbuttons] = nocancellabel;
|
||||||
|
bs->value[bs->nbuttons] = BSDDIALOG_NOCANCEL;
|
||||||
|
if (conf.button.defaultno)
|
||||||
|
bs->curr = bs->nbuttons;
|
||||||
|
bs->nbuttons += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (helplabel != NULL && conf.button.help_button) {
|
||||||
|
bs->label[bs->nbuttons] = helplabel;
|
||||||
|
bs->value[bs->nbuttons] = BSDDIALOG_HELP;
|
||||||
|
bs->nbuttons += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bs->nbuttons == 0) {
|
||||||
|
bs->label[0] = DEFAULT_BUTTON_LABEL;
|
||||||
|
bs->value[0] = DEFAULT_BUTTON_VALUE;
|
||||||
|
bs->nbuttons = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf.button.default_label != NULL) {
|
||||||
|
for (i=0; i<(int)bs->nbuttons; i++) {
|
||||||
|
if (strcmp(conf.button.default_label, bs->label[i]) == 0)
|
||||||
|
bs->curr = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs->sizebutton = MAX(SIZEBUTTON - 2, strlen(bs->label[0]));
|
||||||
|
for (i=1; i < (int) bs->nbuttons; i++)
|
||||||
|
bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i]));
|
||||||
|
bs->sizebutton += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text */
|
||||||
|
|
||||||
|
// old text, to delete in the future
|
||||||
|
enum token { TEXT, WS, END };
|
||||||
|
|
||||||
|
static bool check_set_ncurses_attr(WINDOW *win, char *text)
|
||||||
|
{
|
||||||
|
bool isattr;
|
||||||
|
int colors[8] = {
|
||||||
|
COLOR_BLACK,
|
||||||
|
COLOR_RED,
|
||||||
|
COLOR_GREEN,
|
||||||
|
COLOR_YELLOW,
|
||||||
|
COLOR_BLUE,
|
||||||
|
COLOR_MAGENTA,
|
||||||
|
COLOR_CYAN,
|
||||||
|
COLOR_WHITE
|
||||||
|
};
|
||||||
|
|
||||||
|
if (text[0] == '\0' || text[0] != '\\')
|
||||||
|
return false;
|
||||||
|
if (text[1] == '\0' || text[1] != 'Z')
|
||||||
|
return false;
|
||||||
|
if (text[2] == '\0')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((text[2] - 48) >= 0 && (text[2] - 48) < 8) {
|
||||||
|
// tocheck: import BSD_COLOR
|
||||||
|
// tofix color background
|
||||||
|
wattron(win, COLOR_PAIR(colors[text[2] - 48] * 8 + COLOR_WHITE + 1));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isattr = true;
|
||||||
|
switch (text[2]) {
|
||||||
|
case 'n':
|
||||||
|
wattrset(win, A_NORMAL);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
wattron(win, A_BOLD);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
wattroff(win, A_BOLD);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
wattron(win, A_REVERSE);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
wattroff(win, A_REVERSE);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
wattron(win, A_UNDERLINE);
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
wattroff(win, A_UNDERLINE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isattr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isws(int ch)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ch == ' ' || ch == '\t' || ch == '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
next_token(char *text, char *valuestr)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
enum token tok;
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
|
||||||
|
if (text[0] == '\0')
|
||||||
|
return END;
|
||||||
|
|
||||||
|
while (text[i] != '\0') {
|
||||||
|
if (isws(text[i])) {
|
||||||
|
if (i == 0) {
|
||||||
|
valuestr[0] = text[i];
|
||||||
|
valuestr[1] = '\0';
|
||||||
|
tok = WS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
valuestr[j] = text[i];
|
||||||
|
j++;
|
||||||
|
valuestr[j] = '\0';
|
||||||
|
i++;
|
||||||
|
tok = TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_string(WINDOW *win, int *y, int *x, int minx, int maxx, char *str, bool color)
|
||||||
|
{
|
||||||
|
int i, j, len, reallen;
|
||||||
|
|
||||||
|
if(strlen(str) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = reallen = strlen(str);
|
||||||
|
if (color) {
|
||||||
|
i=0;
|
||||||
|
while (i < len) {
|
||||||
|
if (check_set_ncurses_attr(win, str+i))
|
||||||
|
reallen -= 3;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < len) {
|
||||||
|
if (*x + reallen > maxx) {
|
||||||
|
*y = (*x != minx ? *y+1 : *y);
|
||||||
|
*x = minx;
|
||||||
|
}
|
||||||
|
j = *x;
|
||||||
|
while (j < maxx && i < len) {
|
||||||
|
if (color && check_set_ncurses_attr(win, str+i)) {
|
||||||
|
i += 3;
|
||||||
|
} else {
|
||||||
|
mvwaddch(win, *y, j, str[i]);
|
||||||
|
i++;
|
||||||
|
reallen--;
|
||||||
|
j++;
|
||||||
|
*x = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_text(struct bsddialog_conf conf, WINDOW *pad, int starty, int minx, int maxx,
|
||||||
|
char *text)
|
||||||
|
{
|
||||||
|
char *valuestr;
|
||||||
|
int x, y;
|
||||||
|
bool loop;
|
||||||
|
enum token tok;
|
||||||
|
|
||||||
|
valuestr = malloc(strlen(text) + 1);
|
||||||
|
|
||||||
|
x = minx;
|
||||||
|
y = starty;
|
||||||
|
loop = true;
|
||||||
|
while (loop) {
|
||||||
|
tok = next_token(text, valuestr);
|
||||||
|
switch (tok) {
|
||||||
|
case END:
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case WS:
|
||||||
|
text += strlen(valuestr);
|
||||||
|
print_string(pad, &y, &x, minx, maxx, valuestr, false /*useless*/);
|
||||||
|
break;
|
||||||
|
case TEXT:
|
||||||
|
text += strlen(valuestr);
|
||||||
|
print_string(pad, &y, &x, minx, maxx, valuestr, conf.text.colors);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(valuestr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// new text funcs
|
||||||
|
|
||||||
|
static bool is_ncurses_attr(char *text)
|
||||||
|
{
|
||||||
|
bool isattr;
|
||||||
|
|
||||||
|
if (strnlen(text, 3) < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (text[0] != '\\' || text[1] != 'Z')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((text[2] - '0') >= 0 && (text[2] - '0') < 8)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
isattr = text[2] == 'n' || text[2] == 'b' || text[2] == 'B' ||
|
||||||
|
text[2] == 'r' || text[2] == 'R' || text[2] == 'u' ||
|
||||||
|
text[2] == 'U';
|
||||||
|
|
||||||
|
return isattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool color)
|
||||||
|
{
|
||||||
|
int i, j, len, reallen;
|
||||||
|
|
||||||
|
if(strlen(str) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = reallen = strlen(str);
|
||||||
|
if (color) {
|
||||||
|
i=0;
|
||||||
|
while (i < len) {
|
||||||
|
if (is_ncurses_attr(str+i))
|
||||||
|
reallen -= 3;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < len) {
|
||||||
|
if (*x + reallen > cols) {
|
||||||
|
*y = (*x != 0 ? *y+1 : *y);
|
||||||
|
if (*y >= *rows) {
|
||||||
|
*rows = *y + 1;
|
||||||
|
wresize(win, *rows, cols);
|
||||||
|
}
|
||||||
|
*x = 0;
|
||||||
|
}
|
||||||
|
j = *x;
|
||||||
|
while (j < cols && i < len) {
|
||||||
|
if (color && check_set_ncurses_attr(win, str+i)) {
|
||||||
|
i += 3;
|
||||||
|
} else {
|
||||||
|
mvwaddch(win, *y, j, str[i]);
|
||||||
|
i++;
|
||||||
|
reallen--;
|
||||||
|
j++;
|
||||||
|
*x = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prepare_text(struct bsddialog_conf conf, char *text, char *buf)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
while (text[i] != '\0') {
|
||||||
|
switch (text[i]) {
|
||||||
|
case '\\':
|
||||||
|
buf[j] = '\\';
|
||||||
|
switch (text[i+1]) {
|
||||||
|
case '\\':
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (conf.text.no_nl_expand) {
|
||||||
|
j++;
|
||||||
|
buf[j] = 'n';
|
||||||
|
} else
|
||||||
|
buf[j] = '\n';
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (conf.text.no_collapse) {
|
||||||
|
j++;
|
||||||
|
buf[j] = 't';
|
||||||
|
} else
|
||||||
|
buf[j] = '\t';
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
buf[j] = conf.text.cr_wrap ? ' ' : '\n';
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
buf[j] = conf.text.no_collapse ? '\t' : ' ';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buf[j] = text[i];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
j += (buf[j] == ' ' && conf.text.trim && j > 0 && buf[j-1] == ' ') ?
|
||||||
|
0 : 1;
|
||||||
|
}
|
||||||
|
buf[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_text_properties(struct bsddialog_conf conf, char *text, int *maxword,
|
||||||
|
int *maxline, int *nlines)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int i, buflen, wordlen, linelen;
|
||||||
|
|
||||||
|
if ((buf = malloc(strlen(text) + 1)) == NULL)
|
||||||
|
RETURN_ERROR("Cannot building a buffer to find the properties "\
|
||||||
|
"of the text properties");
|
||||||
|
|
||||||
|
prepare_text(conf, text, buf);
|
||||||
|
|
||||||
|
buflen = strlen(buf) + 1;
|
||||||
|
*maxword = 0;
|
||||||
|
wordlen = 0;
|
||||||
|
for (i=0; i < buflen; i++) {
|
||||||
|
if (buf[i] == '\t' || buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\0')
|
||||||
|
if (wordlen != 0) {
|
||||||
|
*maxword = MAX(*maxword, wordlen);
|
||||||
|
wordlen = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (conf.text.colors && is_ncurses_attr(buf + i))
|
||||||
|
i += 3;
|
||||||
|
else
|
||||||
|
wordlen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*maxline = linelen = 0;
|
||||||
|
*nlines = 1;
|
||||||
|
for (i=0; i < buflen; i++) {
|
||||||
|
switch (buf[i]) {
|
||||||
|
case '\n':
|
||||||
|
*nlines = *nlines + 1;
|
||||||
|
case '\0':
|
||||||
|
*maxline = MAX(*maxline, linelen);
|
||||||
|
linelen = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (conf.text.colors && is_ncurses_attr(buf + i))
|
||||||
|
i += 3;
|
||||||
|
else
|
||||||
|
linelen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*nlines == 1 && *maxline == 0)
|
||||||
|
*nlines = 0;
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_textpad(struct bsddialog_conf conf, WINDOW *pad, int *rows, int cols, char *text)
|
||||||
|
{
|
||||||
|
char *buf, *string;
|
||||||
|
int i, j, x, y;
|
||||||
|
bool loop;
|
||||||
|
|
||||||
|
if ((buf = malloc(strlen(text) + 1)) == NULL)
|
||||||
|
RETURN_ERROR("Cannot build (analyze) text");
|
||||||
|
|
||||||
|
prepare_text(conf, text, buf);
|
||||||
|
|
||||||
|
if ((string = malloc(strlen(text) + 1)) == NULL) {
|
||||||
|
free(buf);
|
||||||
|
RETURN_ERROR("Cannot build (analyze) text");
|
||||||
|
}
|
||||||
|
i = j = x = y = 0;
|
||||||
|
loop = true;
|
||||||
|
while (loop) {
|
||||||
|
string[j] = buf[i];
|
||||||
|
|
||||||
|
if (string[j] == '\0' || string[j] == '\n' ||
|
||||||
|
string[j] == '\t' || string[j] == ' ') {
|
||||||
|
if (j != 0) {
|
||||||
|
string[j] = '\0';
|
||||||
|
print_str(pad, rows, &y, &x, cols, string, conf.text.colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (buf[i]) {
|
||||||
|
case '\0':
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
j = -1;
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
for (j=0; j<4 /*tablen*/; j++) {
|
||||||
|
x++;
|
||||||
|
if (x >= cols) {
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j = -1;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
x++;
|
||||||
|
if (x >= cols) {
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
j = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= *rows) { /* check for whitespaces */
|
||||||
|
*rows = y + 1;
|
||||||
|
wresize(pad, *rows, cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(string);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* autosize */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* max y, that is from 0 to LINES - 1 - t.shadowrows,
|
||||||
|
* could not be max height but avoids problems with checksize
|
||||||
|
*/
|
||||||
|
int widget_max_height(struct bsddialog_conf conf)
|
||||||
|
{
|
||||||
|
int maxheight;
|
||||||
|
|
||||||
|
if ((maxheight = conf.shadow ? LINES - 1 - t.shadowrows : LINES - 1) <= 0)
|
||||||
|
RETURN_ERROR("Terminal too small, LINES - shadow <= 0");
|
||||||
|
|
||||||
|
if (conf.y > 0)
|
||||||
|
if ((maxheight -= conf.y) <=0)
|
||||||
|
RETURN_ERROR("Terminal too small, LINES - shadow - y <= 0");
|
||||||
|
|
||||||
|
return maxheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* max x, that is from 0 to COLS - 1 - t.shadowcols,
|
||||||
|
* * could not be max height but avoids problems with checksize
|
||||||
|
*/
|
||||||
|
int widget_max_width(struct bsddialog_conf conf)
|
||||||
|
{
|
||||||
|
int maxwidth;
|
||||||
|
|
||||||
|
if ((maxwidth = conf.shadow ? COLS - 1 - t.shadowcols : COLS - 1) <= 0)
|
||||||
|
RETURN_ERROR("Terminal too small, COLS - shadow <= 0");
|
||||||
|
if (conf.x > 0)
|
||||||
|
if ((maxwidth -= conf.x) <=0)
|
||||||
|
RETURN_ERROR("Terminal too small, COLS - shadow - x <= 0");
|
||||||
|
|
||||||
|
return maxwidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_widget_size(struct bsddialog_conf conf, int rows, int cols, int *h, int *w)
|
||||||
|
{
|
||||||
|
int maxheight, maxwidth;
|
||||||
|
|
||||||
|
if ((maxheight = widget_max_height(conf)) == BSDDIALOG_ERROR)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (rows == BSDDIALOG_FULLSCREEN)
|
||||||
|
*h = maxheight;
|
||||||
|
else if (rows < BSDDIALOG_FULLSCREEN)
|
||||||
|
RETURN_ERROR("Negative (less than -1) height");
|
||||||
|
else if (rows > BSDDIALOG_AUTOSIZE) {
|
||||||
|
if ((*h = rows) > maxheight)
|
||||||
|
RETURN_ERROR("Height too big (> terminal height - "\
|
||||||
|
"shadow");
|
||||||
|
}
|
||||||
|
/* rows == AUTOSIZE: each widget has to set its size */
|
||||||
|
|
||||||
|
if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (cols == BSDDIALOG_FULLSCREEN)
|
||||||
|
*w = maxwidth;
|
||||||
|
else if (cols < BSDDIALOG_FULLSCREEN)
|
||||||
|
RETURN_ERROR("Negative (less than -1) width");
|
||||||
|
else if (cols > BSDDIALOG_AUTOSIZE) {
|
||||||
|
if ((*w = cols) > maxwidth)
|
||||||
|
RETURN_ERROR("Width too big (> terminal width - shadow)");
|
||||||
|
}
|
||||||
|
/* cols == AUTOSIZE: each widget has to set its size */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_widget_position(struct bsddialog_conf conf, int *y, int *x, int h, int w)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (conf.y == BSDDIALOG_CENTER)
|
||||||
|
*y = LINES/2 - h/2;
|
||||||
|
else if (conf.y < BSDDIALOG_CENTER)
|
||||||
|
RETURN_ERROR("Negative begin y (less than -1)");
|
||||||
|
else if (conf.y >= LINES)
|
||||||
|
RETURN_ERROR("Begin Y under the terminal");
|
||||||
|
else
|
||||||
|
*y = conf.y;
|
||||||
|
|
||||||
|
if ((*y + h + (conf.shadow ? (int) t.shadowrows : 0)) > LINES)
|
||||||
|
RETURN_ERROR("The lower of the box under the terminal "\
|
||||||
|
"(begin Y + height (+ shadow) > terminal lines)");
|
||||||
|
|
||||||
|
|
||||||
|
if (conf.x == BSDDIALOG_CENTER)
|
||||||
|
*x = COLS/2 - w/2;
|
||||||
|
else if (conf.x < BSDDIALOG_CENTER)
|
||||||
|
RETURN_ERROR("Negative begin x (less than -1)");
|
||||||
|
else if (conf.x >= COLS)
|
||||||
|
RETURN_ERROR("Begin X over the right of the terminal");
|
||||||
|
else
|
||||||
|
*x = conf.x;
|
||||||
|
|
||||||
|
if ((*x + w + (conf.shadow ? (int) t.shadowcols : 0)) > COLS)
|
||||||
|
RETURN_ERROR("The right of the box over the terminal "\
|
||||||
|
"(begin X + width (+ shadow) > terminal cols)");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Widgets builders */
|
||||||
|
void
|
||||||
|
draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols,
|
||||||
|
enum elevation elev)
|
||||||
|
{
|
||||||
|
int leftcolor, rightcolor;
|
||||||
|
int ls, rs, ts, bs, tl, tr, bl, br;
|
||||||
|
int ltee, rtee;
|
||||||
|
|
||||||
|
ls = rs = ACS_VLINE;
|
||||||
|
ts = bs = ACS_HLINE;
|
||||||
|
tl = ACS_ULCORNER;
|
||||||
|
tr = ACS_URCORNER;
|
||||||
|
bl = ACS_LLCORNER;
|
||||||
|
br = ACS_LRCORNER;
|
||||||
|
ltee = ACS_LTEE;
|
||||||
|
rtee = ACS_RTEE;
|
||||||
|
|
||||||
|
if (conf.no_lines == false) {
|
||||||
|
if (conf.ascii_lines) {
|
||||||
|
ls = rs = '|';
|
||||||
|
ts = bs = '-';
|
||||||
|
tl = tr = bl = br = ltee = rtee = '+';
|
||||||
|
}
|
||||||
|
leftcolor = elev == RAISED ? t.lineraisecolor : t.linelowercolor;
|
||||||
|
rightcolor = elev == RAISED ? t.linelowercolor : t.lineraisecolor;
|
||||||
|
wattron(win, leftcolor);
|
||||||
|
wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
|
||||||
|
wattroff(win, leftcolor);
|
||||||
|
|
||||||
|
wattron(win, rightcolor);
|
||||||
|
mvwaddch(win, 0, cols-1, tr);
|
||||||
|
mvwvline(win, 1, cols-1, rs, rows-2);
|
||||||
|
mvwaddch(win, rows-1, cols-1, br);
|
||||||
|
mvwhline(win, rows-1, 1, bs, cols-2);
|
||||||
|
wattroff(win, rightcolor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WINDOW *
|
||||||
|
new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols,
|
||||||
|
enum elevation elev)
|
||||||
|
{
|
||||||
|
WINDOW *win;
|
||||||
|
|
||||||
|
if ((win = newwin(rows, cols, y, x)) == NULL) {
|
||||||
|
set_error_string("Cannot build boxed window");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wbkgd(win, t.widgetcolor);
|
||||||
|
|
||||||
|
draw_borders(conf, win, rows, cols, elev);
|
||||||
|
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `enum elevation elev` could be useless because it should be always RAISED,
|
||||||
|
* to check at the end.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
draw_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow,
|
||||||
|
WINDOW *widget, int h, int w, enum elevation elev,
|
||||||
|
WINDOW *textpad, int *htextpad, char *text, bool buttons)
|
||||||
|
{
|
||||||
|
int ts, ltee, rtee;
|
||||||
|
int colorsurroundtitle;
|
||||||
|
|
||||||
|
ts = conf.ascii_lines ? '-' : ACS_HLINE;
|
||||||
|
ltee = conf.ascii_lines ? '+' : ACS_LTEE;
|
||||||
|
rtee = conf.ascii_lines ? '+' : ACS_RTEE;
|
||||||
|
colorsurroundtitle = elev == RAISED ? t.lineraisecolor : t.linelowercolor;
|
||||||
|
|
||||||
|
if (shadow != NULL)
|
||||||
|
wnoutrefresh(shadow);
|
||||||
|
|
||||||
|
// move / resize now or the caller?
|
||||||
|
draw_borders(conf, widget, h, w, elev);
|
||||||
|
|
||||||
|
if (conf.title != NULL) {
|
||||||
|
if (t.surroundtitle && conf.no_lines == false) {
|
||||||
|
wattron(widget, colorsurroundtitle);
|
||||||
|
mvwaddch(widget, 0, w/2 - strlen(conf.title)/2 - 1, rtee);
|
||||||
|
wattroff(widget, colorsurroundtitle);
|
||||||
|
}
|
||||||
|
wattron(widget, t.titlecolor);
|
||||||
|
mvwaddstr(widget, 0, w/2 - strlen(conf.title)/2, conf.title);
|
||||||
|
wattroff(widget, t.titlecolor);
|
||||||
|
if (t.surroundtitle && conf.no_lines == false) {
|
||||||
|
wattron(widget, colorsurroundtitle);
|
||||||
|
waddch(widget, ltee);
|
||||||
|
wattroff(widget, colorsurroundtitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf.hline != NULL) {
|
||||||
|
wattron(widget, t.bottomtitlecolor);
|
||||||
|
wmove(widget, h - 1, w/2 - strlen(conf.hline)/2 - 1);
|
||||||
|
waddch(widget, '[');
|
||||||
|
waddstr(widget, conf.hline);
|
||||||
|
waddch(widget, ']');
|
||||||
|
wattroff(widget, t.bottomtitlecolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textpad == NULL && text != NULL) /* no pad, text null for textbox */
|
||||||
|
print_text(conf, widget, 1, 2, w-3, text);
|
||||||
|
|
||||||
|
if (buttons && conf.no_lines == false) {
|
||||||
|
wattron(widget, t.lineraisecolor);
|
||||||
|
mvwaddch(widget, h-3, 0, ltee);
|
||||||
|
mvwhline(widget, h-3, 1, ts, w-2);
|
||||||
|
wattroff(widget, t.lineraisecolor);
|
||||||
|
|
||||||
|
wattron(widget, t.linelowercolor);
|
||||||
|
mvwaddch(widget, h-3, w-1, rtee);
|
||||||
|
wattroff(widget, t.linelowercolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
wnoutrefresh(widget);
|
||||||
|
|
||||||
|
if (textpad == NULL)
|
||||||
|
return 0; /* widget_init() ends */
|
||||||
|
|
||||||
|
if (text != NULL) /* programbox etc */
|
||||||
|
if (print_textpad(conf, textpad, htextpad,
|
||||||
|
w - HBORDERS - t.texthmargin * 2, text) !=0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `enum elevation elev` could be useless because it should be always RAISED,
|
||||||
|
* to check at the end.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
update_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow,
|
||||||
|
WINDOW *widget, int h, int w, enum elevation elev,
|
||||||
|
WINDOW *textpad, int *htextpad, char *text, bool buttons)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/* nothing for now */
|
||||||
|
|
||||||
|
error = draw_widget_withtextpad(conf, shadow, widget, h, w,
|
||||||
|
elev, textpad, htextpad, text, buttons);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `enum elevation elev` could be useless because it should be always RAISED,
|
||||||
|
* to check at the end.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow,
|
||||||
|
WINDOW **widget, int y, int x, int h, int w, enum elevation elev,
|
||||||
|
WINDOW **textpad, int *htextpad, char *text, bool buttons)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (conf.shadow) {
|
||||||
|
*shadow = newwin(h, w, y + t.shadowrows, x + t.shadowcols);
|
||||||
|
if (*shadow == NULL)
|
||||||
|
RETURN_ERROR("Cannot build shadow");
|
||||||
|
wbkgd(*shadow, t.shadowcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*widget = new_boxed_window(conf, y, x, h, w, elev)) == NULL) {
|
||||||
|
if (conf.shadow)
|
||||||
|
delwin(*shadow);
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textpad == NULL) { /* widget_init() */
|
||||||
|
error = draw_widget_withtextpad(conf, *shadow, *widget, h, w,
|
||||||
|
elev, NULL, NULL, text, buttons);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text != NULL) { /* programbox etc */
|
||||||
|
*htextpad = 1;
|
||||||
|
*textpad = newpad(*htextpad, w - HBORDERS - t.texthmargin * 2);
|
||||||
|
if (*textpad == NULL) {
|
||||||
|
delwin(*textpad);
|
||||||
|
if (conf.shadow)
|
||||||
|
delwin(*shadow);
|
||||||
|
RETURN_ERROR("Cannot build the pad window for text");
|
||||||
|
}
|
||||||
|
wbkgd(*textpad, t.widgetcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = draw_widget_withtextpad(conf, *shadow, *widget, h, w, elev,
|
||||||
|
*textpad, htextpad, text, buttons);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
new_widget(struct bsddialog_conf conf, WINDOW **widget, int *y, int *x,
|
||||||
|
char *text, int *h, int *w, WINDOW **shadow, bool buttons)
|
||||||
|
{
|
||||||
|
|
||||||
|
// to delete (each widget has to check its x,y,h,w)
|
||||||
|
if (*h <= 0)
|
||||||
|
; /* todo */
|
||||||
|
|
||||||
|
if (*w <= 0)
|
||||||
|
; /* todo */
|
||||||
|
|
||||||
|
*y = (conf.y < 0) ? (LINES/2 - *h/2) : conf.y;
|
||||||
|
*x = (conf.x < 0) ? (COLS/2 - *w/2) : conf.x;
|
||||||
|
|
||||||
|
if (new_widget_withtextpad(conf, shadow, widget, *y, *x, *h, *w, RAISED,
|
||||||
|
NULL, NULL, text, buttons) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (conf.shadow)
|
||||||
|
wrefresh(*shadow);
|
||||||
|
|
||||||
|
wrefresh(*widget);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
end_widget_withtextpad(struct bsddialog_conf conf, WINDOW *window, int h, int w,
|
||||||
|
WINDOW *textpad, WINDOW *shadow)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
|
||||||
|
getbegyx(window, y, x); /* for clear, add y & x to args? */
|
||||||
|
|
||||||
|
if (conf.sleep > 0)
|
||||||
|
sleep(conf.sleep);
|
||||||
|
|
||||||
|
if (textpad != NULL)
|
||||||
|
delwin(textpad);
|
||||||
|
|
||||||
|
delwin(window);
|
||||||
|
|
||||||
|
if (conf.shadow)
|
||||||
|
delwin(shadow);
|
||||||
|
|
||||||
|
if (conf.clear)
|
||||||
|
hide_widget(y, x, h, w, shadow != NULL);
|
||||||
|
|
||||||
|
if (conf.get_height != NULL)
|
||||||
|
*conf.get_height = h;
|
||||||
|
if (conf.get_width != NULL)
|
||||||
|
*conf.get_width = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
end_widget(struct bsddialog_conf conf, WINDOW *window, int h, int w,
|
||||||
|
WINDOW *shadow)
|
||||||
|
{
|
||||||
|
|
||||||
|
end_widget_withtextpad(conf, window, h, w, NULL, shadow);
|
||||||
|
}
|
146
lib/lib_util.h
Normal file
146
lib/lib_util.h
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 _LIBBSDDIALOG_UTIL_H_
|
||||||
|
#define _LIBBSDDIALOG_UTIL_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utils to implement widgets - Internal library API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HBORDERS 2
|
||||||
|
#define VBORDERS 2
|
||||||
|
|
||||||
|
/* ncurses has not a Ctrl key macro */
|
||||||
|
#define KEY_CTRL(x) ((x) & 0x1f)
|
||||||
|
|
||||||
|
/* Set default aspect ratio to 9 */
|
||||||
|
#define GET_ASPECT_RATIO(conf) (conf.aspect_ratio > 0 ? conf.aspect_ratio : 9)
|
||||||
|
|
||||||
|
/* debug */
|
||||||
|
#define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \
|
||||||
|
mvprintw(y, x, fmt, __VA_ARGS__); \
|
||||||
|
refresh(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* error buffer */
|
||||||
|
const char *get_error_string(void);
|
||||||
|
void set_error_string(char *string);
|
||||||
|
|
||||||
|
#define RETURN_ERROR(str) do { \
|
||||||
|
set_error_string(str); \
|
||||||
|
return BSDDIALOG_ERROR; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
#define LABEL_cancel_label "Cancel"
|
||||||
|
#define LABEL_exit_label "EXIT"
|
||||||
|
#define LABEL_extra_label "Extra"
|
||||||
|
#define LABEL_help_label "Help"
|
||||||
|
#define LABEL_no_label "No"
|
||||||
|
#define LABEL_ok_label "OK"
|
||||||
|
#define LABEL_yes_label "Yes"
|
||||||
|
#define BUTTONLABEL(l) (conf.button.l != NULL ? conf.button.l : LABEL_ ##l)
|
||||||
|
|
||||||
|
#define MAXBUTTONS 4 /* yes|ok - extra - no|cancel - help */
|
||||||
|
struct buttons {
|
||||||
|
unsigned int nbuttons;
|
||||||
|
char *label[MAXBUTTONS];
|
||||||
|
int value[MAXBUTTONS];
|
||||||
|
int curr;
|
||||||
|
unsigned int sizebutton; /* including left and right delimiters */
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
get_buttons(struct bsddialog_conf conf, struct buttons *bs, char *yesoklabel,
|
||||||
|
char *extralabel, char *nocancellabel, char *helplabel);
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
|
||||||
|
bool shortkey);
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey);
|
||||||
|
|
||||||
|
/* help window with F1 key */
|
||||||
|
int f1help(struct bsddialog_conf conf);
|
||||||
|
|
||||||
|
/* cleaner */
|
||||||
|
int hide_widget(int y, int x, int h, int w, bool withshadow);
|
||||||
|
|
||||||
|
/* (auto) size and (auto) position */
|
||||||
|
int
|
||||||
|
get_text_properties(struct bsddialog_conf conf, char *text, int *maxword,
|
||||||
|
int *maxline, int *nlines);
|
||||||
|
|
||||||
|
int widget_max_height(struct bsddialog_conf conf);
|
||||||
|
int widget_max_width(struct bsddialog_conf conf);
|
||||||
|
|
||||||
|
int
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* widget builders */
|
||||||
|
void
|
||||||
|
print_text(struct bsddialog_conf conf, WINDOW *pad, int starty, int minx,
|
||||||
|
int maxx, char *text);
|
||||||
|
|
||||||
|
enum elevation { RAISED, LOWERED };
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_borders(struct bsddialog_conf conf, WINDOW *win, int rows, int cols,
|
||||||
|
enum elevation elev);
|
||||||
|
|
||||||
|
WINDOW *
|
||||||
|
new_boxed_window(struct bsddialog_conf conf, int y, int x, int rows, int cols,
|
||||||
|
enum elevation elev);
|
||||||
|
|
||||||
|
int
|
||||||
|
new_widget_withtextpad(struct bsddialog_conf conf, WINDOW **shadow,
|
||||||
|
WINDOW **widget, int y, int x, int h, int w, enum elevation elev,
|
||||||
|
WINDOW **textpad, int *htextpad, char *text, bool buttons);
|
||||||
|
|
||||||
|
int
|
||||||
|
update_widget_withtextpad(struct bsddialog_conf conf, WINDOW *shadow,
|
||||||
|
WINDOW *widget, int h, int w, enum elevation elev, WINDOW *textpad,
|
||||||
|
int *htextpad, char *text, bool buttons);
|
||||||
|
|
||||||
|
void
|
||||||
|
end_widget_withtextpad(struct bsddialog_conf conf, WINDOW *window, int h, int w,
|
||||||
|
WINDOW *textpad, WINDOW *shadow);
|
||||||
|
|
||||||
|
int
|
||||||
|
new_widget(struct bsddialog_conf conf, WINDOW **widget, int *y, int *x,
|
||||||
|
char *text, int *h, int *w, WINDOW **shadow, bool buttons);
|
||||||
|
|
||||||
|
void
|
||||||
|
end_widget(struct bsddialog_conf conf, WINDOW *window, int h, int w,
|
||||||
|
WINDOW *shadow);
|
||||||
|
|
||||||
|
#endif
|
142
lib/libbsddialog.c
Normal file
142
lib/libbsddialog.c
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file implements some public function not related to a specific widget.
|
||||||
|
* utils.h/c provides private functions to implement the library.
|
||||||
|
* theme.h/c is public API related to theme.
|
||||||
|
* Widgets implementation:
|
||||||
|
* infobox.c infobox
|
||||||
|
* messgebox.c msgbox - yesno
|
||||||
|
* menubox.c buildlist - checklist - menu - mixedlist - radiolist - treeview
|
||||||
|
* formbox.c inputbox - passwordbox - form - passwordform - mixedform
|
||||||
|
* editorbox.c editbox
|
||||||
|
* barbox.c gauge - mixedgauge - rangebox - pause
|
||||||
|
* timebox.c timebox - calendar
|
||||||
|
* commandbox.c prgbox - programbox - progressbox
|
||||||
|
* tailbox.c tailbox - tailboxbg - textbox
|
||||||
|
* filebox.c dselect - fselect
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
int bsddialog_init(void)
|
||||||
|
{
|
||||||
|
int i, j, c = 1, error = OK;
|
||||||
|
|
||||||
|
set_error_string("");
|
||||||
|
|
||||||
|
if(initscr() == NULL)
|
||||||
|
RETURN_ERROR("Cannot init ncurses (initscr)");
|
||||||
|
|
||||||
|
error += keypad(stdscr, TRUE);
|
||||||
|
nl();
|
||||||
|
error += cbreak();
|
||||||
|
error += noecho();
|
||||||
|
curs_set(0);
|
||||||
|
if(error != OK) {
|
||||||
|
bsddialog_end();
|
||||||
|
RETURN_ERROR("Cannot init ncurses (keypad and cursor)");
|
||||||
|
}
|
||||||
|
|
||||||
|
error += start_color();
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
for(j=0; j<8; j++) {
|
||||||
|
error += init_pair(c, i, j);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
if(error != OK) {
|
||||||
|
bsddialog_end();
|
||||||
|
RETURN_ERROR("Cannot init ncurses (colors)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bsddialog_set_default_theme(BSDDIALOG_THEME_DIALOG) != 0)
|
||||||
|
error = BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_end(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (endwin() != OK)
|
||||||
|
RETURN_ERROR("Cannot end ncurses (endwin)");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_backtitle(struct bsddialog_conf conf, char *backtitle)
|
||||||
|
{
|
||||||
|
|
||||||
|
mvaddstr(0, 1, backtitle);
|
||||||
|
if (conf.no_lines != true)
|
||||||
|
mvhline(1, 1, conf.ascii_lines ? '-' : ACS_HLINE, COLS-2);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *bsddialog_geterror(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return get_error_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_terminalheight(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_terminalwidth(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return COLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bsddialog_initconf(struct bsddialog_conf *conf)
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(conf, 0, sizeof(struct bsddialog_conf));
|
||||||
|
conf->x = conf->y = BSDDIALOG_CENTER;
|
||||||
|
conf->shadow = true;
|
||||||
|
}
|
1015
lib/menubox.c
Normal file
1015
lib/menubox.c
Normal file
File diff suppressed because it is too large
Load diff
278
lib/messagebox.c
Normal file
278
lib/messagebox.c
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Alfonso Sabato Siciliano
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Message": msgbox - yesno */
|
||||||
|
|
||||||
|
#define AUTO_WIDTH (COLS / 3U)
|
||||||
|
/*
|
||||||
|
* Min height = 5: 2 up & down borders + 2 label & up border buttons + 1 line
|
||||||
|
* for text, at least 1 line is important for widget_withtextpad_init() to avoid
|
||||||
|
* "Cannot build the pad window for text".
|
||||||
|
*/
|
||||||
|
#define MIN_HEIGHT 5
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
message_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w,
|
||||||
|
char *text, struct buttons bs)
|
||||||
|
{
|
||||||
|
int maxword, maxline, nlines, line;
|
||||||
|
|
||||||
|
if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (cols == BSDDIALOG_AUTOSIZE) {
|
||||||
|
*w = VBORDERS;
|
||||||
|
/* buttons size */
|
||||||
|
*w += bs.nbuttons * bs.sizebutton;
|
||||||
|
*w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0;
|
||||||
|
/* text size */
|
||||||
|
line = MIN(maxline + VBORDERS + t.texthmargin * 2, AUTO_WIDTH);
|
||||||
|
line = MAX(line, (int) (maxword + VBORDERS + t.texthmargin * 2));
|
||||||
|
*w = MAX(*w, line);
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*w = MIN(*w, widget_max_width(conf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows == BSDDIALOG_AUTOSIZE) {
|
||||||
|
*h = MIN_HEIGHT - 1;
|
||||||
|
if (maxword > 0)
|
||||||
|
*h += MAX(nlines, (*w / GET_ASPECT_RATIO(conf)));
|
||||||
|
*h = MAX(*h, MIN_HEIGHT);
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*h = MIN(*h, widget_max_height(conf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int message_checksize(int rows, int cols, struct buttons bs)
|
||||||
|
{
|
||||||
|
int mincols;
|
||||||
|
|
||||||
|
mincols = VBORDERS;
|
||||||
|
mincols += bs.nbuttons * bs.sizebutton;
|
||||||
|
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.buttonspace : 0;
|
||||||
|
|
||||||
|
if (cols < mincols)
|
||||||
|
RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "\
|
||||||
|
"for borders, buttons and spaces between buttons");
|
||||||
|
|
||||||
|
if (rows < MIN_HEIGHT)
|
||||||
|
RETURN_ERROR("Msgbox and Yesno need at least height 5");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
buttonsupdate(WINDOW *widget, int h, int w, struct buttons bs, bool shortkey)
|
||||||
|
{
|
||||||
|
draw_buttons(widget, h-2, w, bs, shortkey);
|
||||||
|
wnoutrefresh(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
textupdate(WINDOW *widget, int y, int x, int h, int w, WINDOW *textpad,
|
||||||
|
int htextpad, int textrow)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (htextpad > h - 4) {
|
||||||
|
mvwprintw(widget, h-3, w-6, "%3d%%",
|
||||||
|
100 * (textrow+h-4)/ htextpad);
|
||||||
|
wnoutrefresh(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
pnoutrefresh(textpad, textrow, 0, y+1, x+2, y+h-4, x+w-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_widget(struct bsddialog_conf conf, char *text, int rows, int cols,
|
||||||
|
struct buttons bs, bool shortkey)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *textpad, *shadow;
|
||||||
|
bool loop;
|
||||||
|
int i, y, x, h, w, input, output, htextpad, textrow;
|
||||||
|
|
||||||
|
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (message_checksize(h, w, bs) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
|
||||||
|
&textpad, &htextpad, text, true) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
textrow = 0;
|
||||||
|
loop = true;
|
||||||
|
buttonsupdate(widget, h, w, bs, shortkey);
|
||||||
|
textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
|
||||||
|
while(loop) {
|
||||||
|
doupdate();
|
||||||
|
input = getch();
|
||||||
|
switch (input) {
|
||||||
|
case 10: /* Enter */
|
||||||
|
output = bs.value[bs.curr];
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': /* TAB */
|
||||||
|
bs.curr = (bs.curr + 1) % bs.nbuttons;
|
||||||
|
buttonsupdate(widget, h, w, bs, shortkey);
|
||||||
|
break;
|
||||||
|
case KEY_F(1):
|
||||||
|
if (conf.hfile == NULL)
|
||||||
|
break;
|
||||||
|
if (f1help(conf) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
/* No break! the terminal size can change */
|
||||||
|
case KEY_RESIZE:
|
||||||
|
hide_widget(y, x, h, w,conf.shadow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unnecessary, but, when the columns decrease the
|
||||||
|
* following "refresh" seem not work
|
||||||
|
*/
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (message_checksize(h, w, bs) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
wclear(shadow);
|
||||||
|
mvwin(shadow, y + t.shadowrows, x + t.shadowcols);
|
||||||
|
wresize(shadow, h, w);
|
||||||
|
|
||||||
|
wclear(widget);
|
||||||
|
mvwin(widget, y, x);
|
||||||
|
wresize(widget, h, w);
|
||||||
|
|
||||||
|
htextpad = 1;
|
||||||
|
wclear(textpad);
|
||||||
|
wresize(textpad, 1, w - HBORDERS - t.texthmargin * 2);
|
||||||
|
|
||||||
|
if(update_widget_withtextpad(conf, shadow, widget, h, w,
|
||||||
|
RAISED, textpad, &htextpad, text, true) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
buttonsupdate(widget, h, w, bs, shortkey);
|
||||||
|
textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
|
||||||
|
|
||||||
|
/* Important to fix grey lines expanding screen */
|
||||||
|
refresh();
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
if (textrow == 0)
|
||||||
|
break;
|
||||||
|
textrow--;
|
||||||
|
textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (textrow + h - 4 >= htextpad)
|
||||||
|
break;
|
||||||
|
textrow++;
|
||||||
|
textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttonsupdate(widget, h, w, bs, shortkey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttonsupdate(widget, h, w, bs, shortkey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (shortkey == false)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < (int) bs.nbuttons; i++)
|
||||||
|
if (tolower(input) == tolower((bs.label[i])[0])) {
|
||||||
|
output = bs.value[i];
|
||||||
|
loop = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_msgbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
NULL /* nocancel */, BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
return (do_widget(conf, text, rows, cols, bs, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_yesno(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
struct buttons bs;
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(yes_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(no_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
return (do_widget(conf, text, rows, cols, bs, true));
|
||||||
|
}
|
280
lib/textbox.c
Normal file
280
lib/textbox.c
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Alfonso Sabato Siciliano
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
/* "Text": tailbox - tailboxbg - textbox */
|
||||||
|
|
||||||
|
#define BUTTON_TEXTBOX "HELP"
|
||||||
|
|
||||||
|
extern struct bsddialog_theme t;
|
||||||
|
|
||||||
|
enum textmode { TAILMODE, TAILBGMODE, TEXTMODE};
|
||||||
|
|
||||||
|
static void
|
||||||
|
textbox_autosize(struct bsddialog_conf conf, int rows, int cols, int *h, int *w,
|
||||||
|
int hpad, int wpad)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (cols == BSDDIALOG_AUTOSIZE) {
|
||||||
|
*w = VBORDERS;
|
||||||
|
/* buttons size */
|
||||||
|
*w += strlen(BUTTON_TEXTBOX) + 2 /* text delims*/;
|
||||||
|
/* text size */
|
||||||
|
*w = MAX(*w, wpad + VBORDERS);
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*w = MIN(*w, widget_max_width(conf)-1); /* again -1, fix util.c */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows == BSDDIALOG_AUTOSIZE) {
|
||||||
|
*h = hpad + 4; /* HBORDERS + button border */
|
||||||
|
/* avoid terminal overflow */
|
||||||
|
*h = MIN(*h, widget_max_height(conf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int textbox_checksize(int rows, int cols, int hpad, int wpad)
|
||||||
|
{
|
||||||
|
int mincols;
|
||||||
|
|
||||||
|
mincols = VBORDERS + strlen(BUTTON_TEXTBOX) + 2 /* text delims */;
|
||||||
|
|
||||||
|
if (cols < mincols)
|
||||||
|
RETURN_ERROR("Few cols for the textbox");
|
||||||
|
|
||||||
|
if (rows < 4 /* HBORDERS + button*/ + (hpad > 0 ? 1 : 0))
|
||||||
|
RETURN_ERROR("Few rows for the textbox");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_textbox(enum textmode mode, struct bsddialog_conf conf, char* path, int rows, int cols)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *pad, *shadow;
|
||||||
|
int i, input, y, x, h, w, hpad, wpad, ypad, xpad, ys, ye, xs, xe, printrows;
|
||||||
|
char buf[BUFSIZ], *exitbutt;
|
||||||
|
FILE *fp;
|
||||||
|
bool loop;
|
||||||
|
int output;
|
||||||
|
|
||||||
|
if (mode == TAILMODE || mode == TAILBGMODE) {
|
||||||
|
bsddialog_msgbox(conf, "Tailbox and Tailboxbg unimplemented", rows, cols);
|
||||||
|
RETURN_ERROR("Tailbox and Tailboxbg unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fp = fopen(path, "r")) == NULL)
|
||||||
|
RETURN_ERROR("Cannot open file");
|
||||||
|
/*if (mode == TAILMODE) {
|
||||||
|
fseek (fp, 0, SEEK_END);
|
||||||
|
i = nlines = 0;
|
||||||
|
while (i < hpad) {
|
||||||
|
line = ;
|
||||||
|
}
|
||||||
|
for (i=hpad-1; i--; i>=0) {
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
hpad = 1;
|
||||||
|
wpad = 1;
|
||||||
|
pad = newpad(hpad, wpad);
|
||||||
|
wbkgd(pad, t.widgetcolor);
|
||||||
|
i = 0;
|
||||||
|
while(fgets(buf, BUFSIZ, fp) != NULL) {
|
||||||
|
if ((int) strlen(buf) > wpad) {
|
||||||
|
wpad = strlen(buf);
|
||||||
|
wresize(pad, hpad, wpad);
|
||||||
|
}
|
||||||
|
if (i > hpad-1) {
|
||||||
|
hpad++;
|
||||||
|
wresize(pad, hpad, wpad);
|
||||||
|
}
|
||||||
|
mvwaddstr(pad, i, 0, buf);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad);
|
||||||
|
if (textbox_checksize(h, w, hpad, wpad) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
|
||||||
|
NULL, NULL, NULL, true) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
exitbutt = conf.button.exit_label == NULL ? BUTTON_TEXTBOX : conf.button.exit_label;
|
||||||
|
draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2, strlen(exitbutt)+2,
|
||||||
|
exitbutt, true, true);
|
||||||
|
|
||||||
|
wrefresh(widget);
|
||||||
|
|
||||||
|
ys = y + 1;
|
||||||
|
xs = x + 1;
|
||||||
|
ye = ys + h - 5;
|
||||||
|
xe = xs + w - 3;
|
||||||
|
ypad = xpad = 0;
|
||||||
|
printrows = h-4;
|
||||||
|
loop = true;
|
||||||
|
while(loop) {
|
||||||
|
prefresh(pad, ypad, xpad, ys, xs, ye, xe);
|
||||||
|
input = getch();
|
||||||
|
switch(input) {
|
||||||
|
case KEY_ENTER:
|
||||||
|
case 10: /* Enter */
|
||||||
|
output = BSDDIALOG_YESOK;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case KEY_HOME:
|
||||||
|
ypad = 0;
|
||||||
|
break;
|
||||||
|
case KEY_END:
|
||||||
|
ypad = hpad - printrows;
|
||||||
|
ypad = ypad < 0 ? 0 : ypad;
|
||||||
|
break;
|
||||||
|
case KEY_PPAGE:
|
||||||
|
ypad -= printrows;
|
||||||
|
ypad = ypad < 0 ? 0 : ypad;
|
||||||
|
break;
|
||||||
|
case KEY_NPAGE:
|
||||||
|
ypad += printrows;
|
||||||
|
ypad = ypad + printrows > hpad ? hpad - printrows : ypad;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
xpad = 0;
|
||||||
|
case KEY_LEFT:
|
||||||
|
case 'h':
|
||||||
|
xpad = xpad > 0 ? xpad - 1 : 0;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
case 'l':
|
||||||
|
xpad = (xpad + w-2) < wpad-1 ? xpad + 1 : xpad;
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
case 'k':
|
||||||
|
ypad = ypad > 0 ? ypad - 1 : 0;
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
case'j':
|
||||||
|
ypad = ypad + printrows <= hpad -1 ? ypad + 1 : ypad;
|
||||||
|
break;
|
||||||
|
case KEY_F(1):
|
||||||
|
if (conf.hfile == NULL)
|
||||||
|
break;
|
||||||
|
if (f1help(conf) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
/* No break! the terminal size can change */
|
||||||
|
case KEY_RESIZE:
|
||||||
|
hide_widget(y, x, h, w,conf.shadow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unnecessary, but, when the columns decrease the
|
||||||
|
* following "refresh" seem not work
|
||||||
|
*/
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad);
|
||||||
|
if (textbox_checksize(h, w, hpad, wpad) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
if (set_widget_position(conf, &y, &x, h, w) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
wclear(shadow);
|
||||||
|
mvwin(shadow, y + t.shadowrows, x + t.shadowcols);
|
||||||
|
wresize(shadow, h, w);
|
||||||
|
|
||||||
|
wclear(widget);
|
||||||
|
mvwin(widget, y, x);
|
||||||
|
wresize(widget, h, w);
|
||||||
|
|
||||||
|
ys = y + 1;
|
||||||
|
xs = x + 1;
|
||||||
|
ye = ys + h - 5;
|
||||||
|
xe = xs + w - 3;
|
||||||
|
ypad = xpad = 0;
|
||||||
|
printrows = h - 4;
|
||||||
|
|
||||||
|
if(update_widget_withtextpad(conf, shadow, widget, h, w,
|
||||||
|
RAISED, NULL, NULL, NULL, true) != 0)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2,
|
||||||
|
strlen(exitbutt)+2, exitbutt, true, true);
|
||||||
|
|
||||||
|
wrefresh(widget); /* for button */
|
||||||
|
|
||||||
|
/* Important to fix grey lines expanding screen */
|
||||||
|
refresh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_widget_withtextpad(conf, widget, h, w, pad, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_tailbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (do_textbox(TAILMODE, conf, text, rows, cols));
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_tailboxbg(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (do_textbox(TAILBGMODE, conf, text, rows, cols));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int bsddialog_textbox(struct bsddialog_conf conf, char* text, int rows, int cols)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (do_textbox(TEXTMODE, conf, text, rows, cols));
|
||||||
|
}
|
||||||
|
|
286
lib/theme.c
Normal file
286
lib/theme.c
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
#include "bsddialog_theme.h"
|
||||||
|
|
||||||
|
#define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
|
||||||
|
|
||||||
|
struct bsddialog_theme t;
|
||||||
|
|
||||||
|
static struct bsddialog_theme bsddialogtheme = {
|
||||||
|
#define bgwidget COLOR_WHITE
|
||||||
|
#define bgcurr COLOR_YELLOW
|
||||||
|
.shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||||
|
.shadowrows = 1,
|
||||||
|
.shadowcols = 2,
|
||||||
|
|
||||||
|
.backgroundcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
.surroundtitle = true,
|
||||||
|
.titlecolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||||
|
.lineraisecolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||||
|
.linelowercolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||||
|
.widgetcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||||
|
|
||||||
|
.texthmargin = 1,
|
||||||
|
|
||||||
|
.curritemcolor = GET_COLOR(COLOR_WHITE, bgcurr),
|
||||||
|
.itemcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||||
|
.currtagcolor = GET_COLOR(COLOR_BLACK, bgcurr),
|
||||||
|
.tagcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||||
|
.namesepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||||
|
.descsepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
|
||||||
|
|
||||||
|
.currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||||
|
.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
|
||||||
|
.fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE),
|
||||||
|
|
||||||
|
.currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
|
||||||
|
.barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
|
||||||
|
|
||||||
|
.buttonspace = 3,
|
||||||
|
.buttleftch = '[',
|
||||||
|
.buttrightchar = ']',
|
||||||
|
.currbuttdelimcolor = GET_COLOR(COLOR_WHITE, bgcurr),
|
||||||
|
.buttdelimcolor = GET_COLOR(COLOR_BLACK, bgwidget),
|
||||||
|
.currbuttoncolor = GET_COLOR(COLOR_WHITE, bgcurr) | A_UNDERLINE,
|
||||||
|
.buttoncolor = GET_COLOR(COLOR_BLACK, bgwidget) | A_UNDERLINE,
|
||||||
|
.currshortkeycolor = GET_COLOR(COLOR_BLACK, bgcurr) | A_UNDERLINE,
|
||||||
|
.shortkeycolor = GET_COLOR(COLOR_YELLOW, bgwidget) | A_UNDERLINE,
|
||||||
|
|
||||||
|
.bottomtitlecolor= GET_COLOR(COLOR_BLACK, bgwidget)
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bsddialog_theme blackwhite = {
|
||||||
|
#define bk COLOR_BLACK
|
||||||
|
#define fg COLOR_WHITE
|
||||||
|
.shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||||
|
.shadowrows = 1,
|
||||||
|
.shadowcols = 2,
|
||||||
|
|
||||||
|
.backgroundcolor = GET_COLOR(fg, bk),
|
||||||
|
.surroundtitle = true,
|
||||||
|
.titlecolor = GET_COLOR(fg, bk),
|
||||||
|
.lineraisecolor = GET_COLOR(fg, bk),
|
||||||
|
.linelowercolor = GET_COLOR(fg, bk),
|
||||||
|
.widgetcolor = GET_COLOR(fg, bk),
|
||||||
|
|
||||||
|
.texthmargin = 1,
|
||||||
|
|
||||||
|
.curritemcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||||
|
.itemcolor = GET_COLOR(fg, bk),
|
||||||
|
.currtagcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||||
|
.tagcolor = GET_COLOR(fg, bk),
|
||||||
|
.namesepcolor = GET_COLOR(fg, bk),
|
||||||
|
.descsepcolor = GET_COLOR(fg, bk),
|
||||||
|
|
||||||
|
.currfieldcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||||
|
.fieldcolor = GET_COLOR(fg, bk),
|
||||||
|
.fieldreadonlycolor = GET_COLOR(fg, bk),
|
||||||
|
|
||||||
|
.currbarcolor = GET_COLOR(fg, bk) | A_REVERSE,
|
||||||
|
.barcolor = GET_COLOR(fg, bk),
|
||||||
|
|
||||||
|
.buttonspace = 3,
|
||||||
|
.buttleftch = '[',
|
||||||
|
.buttrightchar = ']',
|
||||||
|
.currbuttdelimcolor = GET_COLOR(fg, bk),
|
||||||
|
.buttdelimcolor = GET_COLOR(fg, bk),
|
||||||
|
.currbuttoncolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
|
||||||
|
.buttoncolor = GET_COLOR(fg, bk) | A_UNDERLINE,
|
||||||
|
.currshortkeycolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
|
||||||
|
.shortkeycolor = GET_COLOR(fg, bk) | A_UNDERLINE,
|
||||||
|
|
||||||
|
.bottomtitlecolor= GET_COLOR(fg, bk)
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bsddialog_theme dialogtheme = {
|
||||||
|
.shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||||
|
.shadowrows = 1,
|
||||||
|
.shadowcols = 2,
|
||||||
|
|
||||||
|
.backgroundcolor = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
|
||||||
|
.surroundtitle = false,
|
||||||
|
.titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||||
|
.lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD,
|
||||||
|
.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||||
|
.widgetcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||||
|
|
||||||
|
.texthmargin = 1,
|
||||||
|
|
||||||
|
.curritemcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.itemcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
|
||||||
|
.currtagcolor = GET_COLOR(COLOR_YELLOW,COLOR_BLUE) | A_BOLD,
|
||||||
|
.tagcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||||
|
.namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||||
|
.descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
|
||||||
|
|
||||||
|
.currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||||
|
.fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE)| A_BOLD,
|
||||||
|
|
||||||
|
.currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||||
|
|
||||||
|
.buttonspace = 3,
|
||||||
|
.buttleftch = '<',
|
||||||
|
.buttrightchar = '>',
|
||||||
|
.currbuttdelimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.buttdelimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||||
|
.currbuttoncolor = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD,
|
||||||
|
.buttoncolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
|
||||||
|
.currshortkeycolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.shortkeycolor = GET_COLOR(COLOR_RED, COLOR_WHITE) | A_BOLD,
|
||||||
|
|
||||||
|
.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bsddialog_theme magentatheme = {
|
||||||
|
.shadowcolor = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
|
||||||
|
.shadowrows = 1,
|
||||||
|
.shadowcols = 2,
|
||||||
|
|
||||||
|
.backgroundcolor = GET_COLOR(COLOR_WHITE, COLOR_MAGENTA) | A_BOLD,
|
||||||
|
.surroundtitle = true,
|
||||||
|
.titlecolor = GET_COLOR(COLOR_RED, COLOR_CYAN),
|
||||||
|
.lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||||
|
.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
.widgetcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
|
||||||
|
.texthmargin = 1,
|
||||||
|
|
||||||
|
.curritemcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.itemcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD,
|
||||||
|
.currtagcolor = GET_COLOR(COLOR_YELLOW,COLOR_BLUE) | A_BOLD,
|
||||||
|
.tagcolor = GET_COLOR(COLOR_BLUE, COLOR_CYAN) | A_BOLD,
|
||||||
|
.namesepcolor = GET_COLOR(COLOR_RED, COLOR_CYAN) | A_BOLD,
|
||||||
|
.descsepcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD,
|
||||||
|
|
||||||
|
.currfieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
|
||||||
|
.fieldreadonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE)| A_BOLD,
|
||||||
|
|
||||||
|
.currbarcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
|
||||||
|
.barcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
|
||||||
|
|
||||||
|
.buttonspace = 3,
|
||||||
|
.buttleftch = '<',
|
||||||
|
.buttrightchar = '>',
|
||||||
|
.currbuttdelimcolor = GET_COLOR(COLOR_WHITE, COLOR_RED) | A_BOLD,
|
||||||
|
.buttdelimcolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
.currbuttoncolor = GET_COLOR(COLOR_WHITE, COLOR_RED),
|
||||||
|
.buttoncolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
.currshortkeycolor = GET_COLOR(COLOR_WHITE, COLOR_RED) | A_BOLD,
|
||||||
|
.shortkeycolor = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
|
||||||
|
|
||||||
|
.bottomtitlecolor= GET_COLOR(COLOR_BLACK, COLOR_CYAN) | A_BOLD
|
||||||
|
};
|
||||||
|
|
||||||
|
void bsddialog_set_theme(struct bsddialog_theme newtheme)
|
||||||
|
{
|
||||||
|
t.shadowcolor = newtheme.shadowcolor;
|
||||||
|
t.shadowrows = newtheme.shadowrows;
|
||||||
|
t.shadowcols = newtheme.shadowcols;
|
||||||
|
|
||||||
|
t.backgroundcolor = newtheme.backgroundcolor;
|
||||||
|
t.surroundtitle = newtheme.surroundtitle;
|
||||||
|
t.titlecolor = newtheme.titlecolor;
|
||||||
|
t.lineraisecolor = newtheme.lineraisecolor;
|
||||||
|
t.linelowercolor = newtheme.linelowercolor;
|
||||||
|
t.widgetcolor = newtheme.widgetcolor;
|
||||||
|
|
||||||
|
t.texthmargin = newtheme.texthmargin;
|
||||||
|
|
||||||
|
t.curritemcolor = newtheme.curritemcolor;
|
||||||
|
t.itemcolor = newtheme.itemcolor;
|
||||||
|
t.currtagcolor = newtheme.currtagcolor;
|
||||||
|
t.tagcolor = newtheme.tagcolor;
|
||||||
|
t.namesepcolor = newtheme.namesepcolor;
|
||||||
|
t.descsepcolor = newtheme.descsepcolor;
|
||||||
|
|
||||||
|
t.currfieldcolor = newtheme.currfieldcolor;
|
||||||
|
t.fieldcolor = newtheme.fieldcolor;
|
||||||
|
t.fieldreadonlycolor = newtheme.fieldreadonlycolor;
|
||||||
|
|
||||||
|
t.currbarcolor = newtheme.currbarcolor;
|
||||||
|
t.barcolor = newtheme.barcolor;
|
||||||
|
|
||||||
|
t.buttonspace = newtheme.buttonspace;
|
||||||
|
t.buttleftch = newtheme.buttleftch;
|
||||||
|
t.buttrightchar = newtheme.buttrightchar;
|
||||||
|
t.currbuttdelimcolor = newtheme.currbuttdelimcolor;
|
||||||
|
t.buttdelimcolor = newtheme.buttdelimcolor;
|
||||||
|
t.currbuttoncolor = newtheme.currbuttoncolor;
|
||||||
|
t.buttoncolor = newtheme.buttoncolor;
|
||||||
|
t.currshortkeycolor = newtheme.currshortkeycolor;
|
||||||
|
t.shortkeycolor = newtheme.shortkeycolor;
|
||||||
|
|
||||||
|
t.bottomtitlecolor = newtheme.bottomtitlecolor;
|
||||||
|
|
||||||
|
bkgd(t.backgroundcolor);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (newtheme == BSDDIALOG_THEME_DEFAULT)
|
||||||
|
bsddialog_set_theme(dialogtheme);
|
||||||
|
else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
|
||||||
|
bsddialog_set_theme(bsddialogtheme);
|
||||||
|
else if (newtheme == BSDDIALOG_THEME_BLACKWHITE)
|
||||||
|
bsddialog_set_theme(blackwhite);
|
||||||
|
else if (newtheme == BSDDIALOG_THEME_DIALOG)
|
||||||
|
bsddialog_set_theme(dialogtheme);
|
||||||
|
else if (newtheme == BSDDIALOG_THEME_MAGENTA)
|
||||||
|
bsddialog_set_theme(magentatheme);
|
||||||
|
else
|
||||||
|
RETURN_ERROR("Unknow default theme");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bsddialog_color(enum bsddialog_color background, enum bsddialog_color foreground)
|
||||||
|
{
|
||||||
|
|
||||||
|
return GET_COLOR(background, foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bsddialog_theme bsddialog_get_theme()
|
||||||
|
{
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
241
lib/timebox.c
Normal file
241
lib/timebox.c
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef PORTNCURSES
|
||||||
|
#include <ncurses/curses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsddialog.h"
|
||||||
|
#include "lib_util.h"
|
||||||
|
|
||||||
|
/* "Time": timebox - calendar */
|
||||||
|
|
||||||
|
int bsddialog_timebox(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int *hh, unsigned int *mm, unsigned int *ss)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *shadow;
|
||||||
|
int i, input, output, y, x, sel;
|
||||||
|
struct buttons bs;
|
||||||
|
bool loop, buttupdate;
|
||||||
|
|
||||||
|
if (hh == NULL || mm == NULL || ss == NULL)
|
||||||
|
RETURN_ERROR("hh or mm or ss == NULL");
|
||||||
|
|
||||||
|
struct myclockstruct {
|
||||||
|
unsigned int max;
|
||||||
|
unsigned int curr;
|
||||||
|
WINDOW *win;
|
||||||
|
} c[3] = { {23, *hh, NULL}, {59, *mm, NULL}, {59, *ss, NULL} };
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
c[0].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 7, 3, 4, LOWERED);
|
||||||
|
mvwaddch(widget, rows - 5, cols/2 - 3, ':');
|
||||||
|
c[1].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 2, 3, 4, LOWERED);
|
||||||
|
mvwaddch(widget, rows - 5, cols/2 + 2, ':');
|
||||||
|
c[2].win = new_boxed_window(conf, y + rows - 6, x + cols/2 + 3, 3, 4, LOWERED);
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
sel=0;
|
||||||
|
curs_set(2);
|
||||||
|
loop = buttupdate = true;
|
||||||
|
while(loop) {
|
||||||
|
if (buttupdate) {
|
||||||
|
draw_buttons(widget, rows-2, cols, bs, true);
|
||||||
|
wrefresh(widget);
|
||||||
|
buttupdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
mvwprintw(c[i].win, 1, 1, "%2d", c[i].curr);
|
||||||
|
wrefresh(c[i].win);
|
||||||
|
}
|
||||||
|
wmove(c[sel].win, 1, 2);
|
||||||
|
wrefresh(c[sel].win);
|
||||||
|
|
||||||
|
input = getch();
|
||||||
|
switch(input) {
|
||||||
|
case 10: /* Enter */
|
||||||
|
output = bs.value[bs.curr];
|
||||||
|
if (output == BSDDIALOG_YESOK) {
|
||||||
|
*hh = c[0].curr - 1900;
|
||||||
|
*mm = c[1].curr;
|
||||||
|
*ss = c[2].curr;
|
||||||
|
}
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: /* Esc */
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': /* TAB */
|
||||||
|
sel = (sel + 1) % 3;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
c[sel].curr = c[sel].curr < c[sel].max ? c[sel].curr + 1 : 0;
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
c[sel].curr = c[sel].curr > 0 ? c[sel].curr - 1 : c[sel].max;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curs_set(0);
|
||||||
|
|
||||||
|
for (i=0; i<3; i++)
|
||||||
|
delwin(c[i].win);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsddialog_calendar(struct bsddialog_conf conf, char* text, int rows, int cols,
|
||||||
|
unsigned int *yy, unsigned int *mm, unsigned int *dd)
|
||||||
|
{
|
||||||
|
WINDOW *widget, *shadow;
|
||||||
|
int i, input, output, y, x, sel;
|
||||||
|
struct buttons bs;
|
||||||
|
bool loop, buttupdate;
|
||||||
|
|
||||||
|
if (yy == NULL || mm == NULL || dd == NULL)
|
||||||
|
RETURN_ERROR("yy or mm or dd == NULL");
|
||||||
|
|
||||||
|
struct calendar {
|
||||||
|
unsigned int max;
|
||||||
|
unsigned int curr;
|
||||||
|
WINDOW *win;
|
||||||
|
unsigned int x;
|
||||||
|
} c[3] = {{9999, *yy, NULL, 4 }, {12, *mm, NULL, 9 }, {31, *dd, NULL, 2 }};
|
||||||
|
struct month {
|
||||||
|
char *name;
|
||||||
|
unsigned int days;
|
||||||
|
} m[12] = {
|
||||||
|
{ "January", 30 }, { "February", 30 }, { "March", 30 },
|
||||||
|
{ "April", 30 }, { "May", 30 }, { "June", 30 },
|
||||||
|
{ "July", 30 }, { "August", 30 }, { "September", 30 },
|
||||||
|
{ "October", 30 }, { "November", 30 }, { "December", 30 }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (new_widget(conf, &widget, &y, &x, text, &rows, &cols, &shadow,
|
||||||
|
true) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
c[0].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 12, 3, 6, LOWERED);
|
||||||
|
mvwaddch(widget, rows - 5, cols/2 - 6, '/');
|
||||||
|
c[1].win = new_boxed_window(conf, y + rows - 6, x + cols/2 - 5, 3, 11, LOWERED);
|
||||||
|
mvwaddch(widget, rows - 5, cols/2 + 6, '/');
|
||||||
|
c[2].win = new_boxed_window(conf, y + rows - 6, x + cols/2 + 7, 3, 4, LOWERED);
|
||||||
|
|
||||||
|
wrefresh(widget);
|
||||||
|
|
||||||
|
get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
|
||||||
|
BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
|
||||||
|
|
||||||
|
sel=2;
|
||||||
|
curs_set(2);
|
||||||
|
loop = buttupdate = true;
|
||||||
|
while(loop) {
|
||||||
|
if (buttupdate) {
|
||||||
|
draw_buttons(widget, rows-2, cols, bs, true);
|
||||||
|
wrefresh(widget);
|
||||||
|
buttupdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mvwprintw(c[0].win, 1, 1, "%4d", c[0].curr);
|
||||||
|
mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].curr-1].name);
|
||||||
|
mvwprintw(c[2].win, 1, 1, "%2d", c[2].curr);
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
wrefresh(c[i].win);
|
||||||
|
}
|
||||||
|
wmove(c[sel].win, 1, c[sel].x);
|
||||||
|
wrefresh(c[sel].win);
|
||||||
|
|
||||||
|
input = getch();
|
||||||
|
switch(input) {
|
||||||
|
case 10: // Enter
|
||||||
|
output = bs.value[bs.curr]; // values -> outputs
|
||||||
|
if (output == BSDDIALOG_YESOK) {
|
||||||
|
*yy = c[0].curr - 1900;
|
||||||
|
*mm = c[1].curr;
|
||||||
|
*dd = c[2].curr;
|
||||||
|
}
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case 27: // Esc
|
||||||
|
output = BSDDIALOG_ESC;
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
case '\t': // TAB
|
||||||
|
sel = (sel + 1) % 3;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (bs.curr > 0) {
|
||||||
|
bs.curr--;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (bs.curr < (int) bs.nbuttons - 1) {
|
||||||
|
bs.curr++;
|
||||||
|
buttupdate = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
c[sel].curr = c[sel].curr < c[sel].max ? c[sel].curr + 1 : 1;
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
c[sel].curr = c[sel].curr > 1 ? c[sel].curr - 1 : c[sel].max;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curs_set(0);
|
||||||
|
|
||||||
|
for (i=0; i<3; i++)
|
||||||
|
delwin(c[i].win);
|
||||||
|
end_widget(conf, widget, rows, cols, shadow);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
library_examples/buildlist.c
Normal file
44
library_examples/buildlist.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", false, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
|
||||||
|
{"", true, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
|
||||||
|
{"", false, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
|
||||||
|
{"", true, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
|
||||||
|
{"", false, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "radiolist";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_buildlist(conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Buildlist:\n");
|
||||||
|
for (i=0; i<5; i++)
|
||||||
|
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
library_examples/checklist.c
Normal file
44
library_examples/checklist.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
|
||||||
|
{"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
|
||||||
|
{"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
|
||||||
|
{"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
|
||||||
|
{"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "checklist";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_checklist(conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Checklist:\n");
|
||||||
|
for (i=0; i<5; i++)
|
||||||
|
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
10
library_examples/compile
Executable file
10
library_examples/compile
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
libpath=../lib
|
||||||
|
examples="buildlist menu treeview checklist radiolist mixedlist theme \
|
||||||
|
infobox yesno msgbox ports"
|
||||||
|
|
||||||
|
for e in $examples
|
||||||
|
do
|
||||||
|
cc -g -Wall -I$libpath ${e}.c -o $e -L$libpath -lbsddialog -Wl,-rpath=$libpath
|
||||||
|
done
|
32
library_examples/infobox.c
Normal file
32
library_examples/infobox.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "infobox";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_infobox(conf, "Example", 7, 20);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
library_examples/menu.c
Normal file
44
library_examples/menu.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
|
||||||
|
{"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
|
||||||
|
{"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
|
||||||
|
{"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
|
||||||
|
{"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "menu";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_menu(conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Menu:\n");
|
||||||
|
for (i=0; i<5; i++)
|
||||||
|
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
71
library_examples/mixedlist.c
Normal file
71
library_examples/mixedlist.c
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
/* Actually this is an example for mixedmenu to reproduce dialog4ports(1) */
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, j, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem item;
|
||||||
|
struct bsddialog_menuitem check[5] = {
|
||||||
|
{ "+", true, 0, "Name 1", "Desc 1", "Bottom Desc 1" },
|
||||||
|
{ "" , false, 0, "Name 2", "Desc 2", "Bottom Desc 2" },
|
||||||
|
{ "+", true, 0, "Name 3", "Desc 3", "Bottom Desc 3" },
|
||||||
|
{ "" , false, 0, "Name 4", "Desc 4", "Bottom Desc 4" },
|
||||||
|
{ "+", true, 0, "Name 5", "Desc 5", "Bottom Desc 5" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem sep[1] = {
|
||||||
|
{ "", true, 0, "Radiolist", "(desc)", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem radio[5] = {
|
||||||
|
{ "", true, 0, "Name 1", "Desc 1", "Bottom Desc 1" },
|
||||||
|
{ "+", false, 0, "Name 2", "Desc 2", "Bottom Desc 2" },
|
||||||
|
{ "", false, 0, "Name 3", "Desc 3", "Bottom Desc 3" },
|
||||||
|
{ "+", false, 0, "Name 4", "Desc 4", "Bottom Desc 4" },
|
||||||
|
{ "", false, 0, "Name 5", "Desc 5", "Bottom Desc 5" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menugroup group[3] = {
|
||||||
|
{ BSDDIALOG_CHECKLIST, 5, check },
|
||||||
|
{ BSDDIALOG_SEPARATOR, 1, sep },
|
||||||
|
{ BSDDIALOG_RADIOLIST, 5, radio }
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "mixedmenu";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_mixedlist(conf, "dialog4ports", 20, 30, 11, 3, group,
|
||||||
|
NULL,NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Mixedlist (dialog4ports):\n");
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
for (j=0; j<group[i].nitems; j++) {
|
||||||
|
item = group[i].items[j];
|
||||||
|
if (group[i].type == BSDDIALOG_SEPARATOR)
|
||||||
|
printf("----- %s -----\n", item.name);
|
||||||
|
else if (group[i].type == BSDDIALOG_RADIOLIST)
|
||||||
|
printf(" (%c) %s\n", item.on ? '*' : ' ', item.name);
|
||||||
|
else /* BSDDIALOG_PORTCHECKLIST */
|
||||||
|
printf(" [%c] %s\n", item.on ? 'X' : ' ', item.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
42
library_examples/msgbox.c
Normal file
42
library_examples/msgbox.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int input;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
|
||||||
|
/* Configuration */
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "msgbox";
|
||||||
|
|
||||||
|
/* Run BSDDialog */
|
||||||
|
if (bsddialog_init() == BSDDIALOG_ERROR) {
|
||||||
|
printf("Error: %s\n", bsddialog_geterror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
input = bsddialog_msgbox(conf, "Example", 7, 20);
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
/* User Input */
|
||||||
|
printf("User input: ");
|
||||||
|
switch (input) {
|
||||||
|
case BSDDIALOG_ERROR: printf("Error %s\n", bsddialog_geterror()); break;
|
||||||
|
case BSDDIALOG_YESOK: printf("OK\n"); break;
|
||||||
|
case BSDDIALOG_ESC: printf("ESC\n"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
97
library_examples/ports.c
Normal file
97
library_examples/ports.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
/* Actually this is an example for mixedmenu to reproduce dialog4ports(1) */
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, j, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem item;
|
||||||
|
|
||||||
|
struct bsddialog_menuitem check1[5] = {
|
||||||
|
{ "+", true, 0, "CSCOPE", "cscope support", "" },
|
||||||
|
{ "+", true, 0, "DEFAULT_VIMRC", "Install bundled vimrc as default setting", "" },
|
||||||
|
{ "", false, 0, "MAKE_JOBS", "Enable parallel build", "" },
|
||||||
|
{ "", true, 0, "NLS", "Native Language Support", "" },
|
||||||
|
{ "+", false, 0, "XTERM_SAVE", "Restore xterm screen after exit", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem sep1[1] = {
|
||||||
|
{ "", true, 0, "Optional language bindings", "", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem check2[6] = {
|
||||||
|
{ "", false, 0, "LUA", "Lua scripting language support", "" },
|
||||||
|
{ "+", true, 0, "PERL", "Perl scripting language support", "" },
|
||||||
|
{ "", true, 0, "PYTHON", "Python bindings or support", "" },
|
||||||
|
{ "+", true, 0, "RUBY", "Ruby bindings or support", "" },
|
||||||
|
{ "", false, 0, "SCHEME", "MzScheme (Racket) bindings", "" },
|
||||||
|
{ "", false, 0, "TCL", "Tcl scripting language support", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem sep2[1] = {
|
||||||
|
{ "", true, 0, "CTAGS", "", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem radio1[3] = {
|
||||||
|
{ "+", false, 0, "CTAGS_BASE", "Use system ctags", "" },
|
||||||
|
{ "", true, 0, "CTAGS_EXUBERANT", "Use exctags instead of ctags", "" },
|
||||||
|
{ "", false, 0, "CTAGS_UNIVERSAL", "Use uctags instead of ctags", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem sep3[1] = {
|
||||||
|
{ "", true, 0, "User interface", "", "" }
|
||||||
|
};
|
||||||
|
struct bsddialog_menuitem radio2[7] = {
|
||||||
|
{ "", false, 0, "ATHENA", "Athena GUI toolkit", "" },
|
||||||
|
{ "", false, 0, "CONSOLE","Console/terminal mode", "" },
|
||||||
|
{ "", false, 0, "GNOME", "GNOME desktop environment support", "" },
|
||||||
|
{ "", false, 0, "GTK2", "GTK+ 2 GUI toolkit support", "" },
|
||||||
|
{ "", true, 0, "GTK3", "GTK+ 3 GUI toolkit support", "" },
|
||||||
|
{ "", false, 0, "MOTIF", "Motif widget library support", "" },
|
||||||
|
{ "", false, 0, "X11", "X11 (graphics) support", "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bsddialog_menugroup group[7] = {
|
||||||
|
{ BSDDIALOG_CHECKLIST, 5, check1 },
|
||||||
|
{ BSDDIALOG_SEPARATOR, 1, sep1 },
|
||||||
|
{ BSDDIALOG_CHECKLIST, 6, check2 },
|
||||||
|
{ BSDDIALOG_SEPARATOR, 1, sep2 },
|
||||||
|
{ BSDDIALOG_RADIOLIST, 3, radio1 },
|
||||||
|
{ BSDDIALOG_SEPARATOR, 1, sep3 },
|
||||||
|
{ BSDDIALOG_RADIOLIST, 7, radio2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "vim-8.2.2569";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_mixedlist(conf, "", 0, 0, 0, 7, group, NULL,NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Options:\n");
|
||||||
|
for (i=0; i<7; i++) {
|
||||||
|
for (j=0; j<group[i].nitems; j++) {
|
||||||
|
item = group[i].items[j];
|
||||||
|
if (group[i].type == BSDDIALOG_SEPARATOR)
|
||||||
|
printf("----- %s -----\n", item.name);
|
||||||
|
else if (group[i].type == BSDDIALOG_RADIOLIST)
|
||||||
|
printf(" (%c) %s\n", item.on ? '*' : ' ', item.name);
|
||||||
|
else /* BSDDIALOG_PORTCHECKLIST */
|
||||||
|
printf(" [%c] %s\n", item.on ? 'X' : ' ', item.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
library_examples/radiolist.c
Normal file
44
library_examples/radiolist.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
|
||||||
|
{"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
|
||||||
|
{"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
|
||||||
|
{"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
|
||||||
|
{"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "radiolist";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_radiolist(conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Radiolist:\n");
|
||||||
|
for (i=0; i<5; i++)
|
||||||
|
printf(" (%c) %s\n", items[i].on ? '*' : ' ', items[i].name);
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
67
library_examples/theme.c
Normal file
67
library_examples/theme.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
#include <bsddialog_theme.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
enum bsddialog_default_theme theme;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", false, 0, "Dialog", "Current dialog theme", "BSDDIALOG_THEME_DIALOG" },
|
||||||
|
{"", false, 0, "BSDDialog", "Future default theme", "BSDDIALOG_THEME_DEFAULT"},
|
||||||
|
{"", false, 0, "BlackWhite","Black and White theme", "BSDDIALOG_THEME_BLACKWHITE"},
|
||||||
|
{"", false, 0, "Magenta", "Testing", "BSDDIALOG_THEME_MAGENTA"},
|
||||||
|
{"", false, 0, "Quit", "Exit", "Quit or Cancel to exit" }
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = " Theme ";
|
||||||
|
|
||||||
|
if (bsddialog_init() == BSDDIALOG_ERROR)
|
||||||
|
return BSDDIALOG_ERROR;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
bsddialog_backtitle(conf, "Theme Example");
|
||||||
|
|
||||||
|
output = bsddialog_menu(conf, "Choose theme", 15, 40, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
if (output != BSDDIALOG_YESOK || items[4].on)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (items[0].on) {
|
||||||
|
theme = BSDDIALOG_THEME_DIALOG;
|
||||||
|
conf.menu.default_item = items[0].name;
|
||||||
|
}
|
||||||
|
else if (items[1].on) {
|
||||||
|
theme = BSDDIALOG_THEME_BSDDIALOG;
|
||||||
|
conf.menu.default_item = items[1].name;
|
||||||
|
}
|
||||||
|
else if (items[2].on) {
|
||||||
|
theme = BSDDIALOG_THEME_BLACKWHITE;
|
||||||
|
conf.menu.default_item = items[2].name;
|
||||||
|
}
|
||||||
|
else if (items[3].on) {
|
||||||
|
theme = BSDDIALOG_THEME_MAGENTA;
|
||||||
|
conf.menu.default_item = items[3].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bsddialog_set_default_theme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
library_examples/treeview.c
Normal file
44
library_examples/treeview.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
struct bsddialog_menuitem items[5] = {
|
||||||
|
{"", false, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
|
||||||
|
{"", false, 1, "Name 2", "Desc 2", "Bottom Desc 2"},
|
||||||
|
{"", false, 1, "Name 3", "Desc 3", "Bottom Desc 3"},
|
||||||
|
{"", false, 2, "Name 4", "Desc 4", "Bottom Desc 4"},
|
||||||
|
{"", false, 1, "Name 5", "Desc 5", "Bottom Desc 5"}
|
||||||
|
};
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "radiolist";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_treeview(conf, "Example", 15, 30, 5, 5, items, NULL);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
printf("Treeview:\n");
|
||||||
|
for (i=0; i<5; i++)
|
||||||
|
printf(" (%c) %s\n", items[i].on ? '*' : ' ', items[i].name);
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
32
library_examples/yesno.c
Normal file
32
library_examples/yesno.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*
|
||||||
|
* Written in 2021 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <bsddialog.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
struct bsddialog_conf conf;
|
||||||
|
|
||||||
|
bsddialog_initconf(&conf);
|
||||||
|
conf.title = "yesno";
|
||||||
|
|
||||||
|
if (bsddialog_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
output = bsddialog_yesno(conf, "Example", 7, 25);
|
||||||
|
|
||||||
|
bsddialog_end();
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
20
utility_examples/gauge_example.sh
Executable file
20
utility_examples/gauge_example.sh
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
input="A B C D E F G"
|
||||||
|
total=`echo $input | awk '{print split($0, a)}'`
|
||||||
|
curr=1
|
||||||
|
for i in $input
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
perc="$(expr $(expr $curr "*" 100 ) "/" $total )"
|
||||||
|
echo XXX
|
||||||
|
echo $perc
|
||||||
|
echo "[$curr/$total] Input: $i"
|
||||||
|
echo XXX
|
||||||
|
if [ $curr -eq $total ]
|
||||||
|
then
|
||||||
|
echo EOF
|
||||||
|
fi
|
||||||
|
curr=`expr $curr + 1`
|
||||||
|
done | ./bsddialog --title gauge --gauge "[0/$total] Starting..." 10 70 0
|
||||||
|
|
3
utility_examples/info_example.sh
Executable file
3
utility_examples/info_example.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./bsddialog --sleep 5 --title infobox --infobox "Hello World!\n5 seconds" 6 20
|
41
utility_examples/menu_example.sh
Executable file
41
utility_examples/menu_example.sh
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./bsddialog --title menu --menu "Hello World!" 15 30 5 \
|
||||||
|
"Tag 1" "DESC 1 xyz" \
|
||||||
|
"Tag 2" "DESC 2 xyz" \
|
||||||
|
"Tag 3" "DESC 3 xyz" \
|
||||||
|
"Tag 4" "DESC 4 xyz" \
|
||||||
|
"Tag 5" "DESC 5 xyz" \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --title checklist --checklist "Hello World!" 15 30 5 \
|
||||||
|
"Tag 1" "DESC 1 xyz" on \
|
||||||
|
"Tag 2" "DESC 2 xyz" off \
|
||||||
|
"Tag 3" "DESC 3 xyz" on \
|
||||||
|
"Tag 4" "DESC 4 xyz" off \
|
||||||
|
"Tag 5" "DESC 5 xyz" on \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --title radiolist --radiolist "Hello World!" 15 30 5 \
|
||||||
|
"Tag 1" "DESC 1 xyz" off \
|
||||||
|
"Tag 2" "DESC 2 xyz" off \
|
||||||
|
"Tag 3" "DESC 3 xyz" on \
|
||||||
|
"Tag 4" "DESC 4 xyz" off \
|
||||||
|
"Tag 5" "DESC 5 xyz" off \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --title buildlist --buildlist "Hello World!" 15 40 5 \
|
||||||
|
"Tag 1" "DESC 1 xyz" off \
|
||||||
|
"Tag 2" "DESC 2 xyz" off \
|
||||||
|
"Tag 3" "DESC 3 xyz" on \
|
||||||
|
"Tag 4" "DESC 4 xyz" off \
|
||||||
|
"Tag 5" "DESC 5 xyz" off \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --title treeview --treeview "Hello World!" 15 40 5 \
|
||||||
|
0 "Tag 1" "DESC 1 xyz" off \
|
||||||
|
1 "Tag 2" "DESC 2 xyz" off \
|
||||||
|
2 "Tag 3" "DESC 3 xyz" on \
|
||||||
|
1 "Tag 4" "DESC 4 xyz" off \
|
||||||
|
1 "Tag 5" "DESC 5 xyz" off \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
5
utility_examples/message_example.sh
Executable file
5
utility_examples/message_example.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./bsddialog --title msgbox --msgbox "Hello World!" 6 20
|
||||||
|
|
||||||
|
./bsddialog --title yesno --yesno "Hello World!" 6 25
|
25
utility_examples/mixedform_example.sh
Executable file
25
utility_examples/mixedform_example.sh
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./bsddialog --title mixedform --mixedform "Hello World!" 12 40 5 \
|
||||||
|
Label: 1 1 Entry 1 11 18 25 0 \
|
||||||
|
Label: 2 1 Read-Only 2 11 18 25 2 \
|
||||||
|
Password: 3 1 Value2 3 11 18 25 1 \
|
||||||
|
Password: 4 1 Value4 4 11 18 25 3 \
|
||||||
|
Label5: 5 1 Value5 5 11 18 25 4 \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --backtitle "BSD-2-Clause Licese" --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 \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
||||||
|
|
||||||
|
./bsddialog --title passwordform --passwordform "Hello World!" 12 40 5 \
|
||||||
|
Password1: 1 1 Value1 1 12 18 25 \
|
||||||
|
Password2: 2 1 Value2 2 12 18 25 \
|
||||||
|
Password3: 3 1 Value3 3 12 18 25 \
|
||||||
|
Password4: 4 1 Value4 4 12 18 25 \
|
||||||
|
Password5: 5 1 Value5 5 12 18 25 \
|
||||||
|
2>out.txt ; cat out.txt ; rm out.txt
|
24
utility_examples/mixedgauge_example.sh
Executable file
24
utility_examples/mixedgauge_example.sh
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
input="A B C D E F G H"
|
||||||
|
total=`echo $input | awk '{print split($0, a)}'`
|
||||||
|
curr=1
|
||||||
|
for i in $input
|
||||||
|
do
|
||||||
|
perc="$(expr $(expr $curr "*" 100 ) "/" $total )"
|
||||||
|
curr=`expr $curr + 1`
|
||||||
|
./bsddialog --title " mixedgauge " --mixedgauge "Hello World! Press <ENTER>" 20 35 $perc \
|
||||||
|
"Hidden!" 8 \
|
||||||
|
"Label 1" 0 \
|
||||||
|
"Label 2" 1 \
|
||||||
|
"Label 3" 2 \
|
||||||
|
"Label 4" 3 \
|
||||||
|
"Label 5" 4 \
|
||||||
|
"Label 6" 5 \
|
||||||
|
"Label 7" 6 \
|
||||||
|
"Label 8" 7 \
|
||||||
|
"Label 9" 9 \
|
||||||
|
"Label X" -- -$perc
|
||||||
|
#sleep 1
|
||||||
|
done
|
||||||
|
|
Loading…
Reference in a new issue