contrib/bsddialog: import 1.1

Add: slider dialog.
Imported to enable testing and to complete the geomman(8) utility.

Developed as part of the "Full Disk Administration Tool for FreeBSD"
project, Braulio Rivas (brauliorivas@), Google Summer of Code 2025.

Sponsored by:	Google LLC (GSoC 2025)
This commit is contained in:
Braulio Rivas
2025-11-03 21:14:09 +01:00
committed by Alfonso S. Siciliano
parent 653f765f05
commit 5a70558d32
13 changed files with 853 additions and 34 deletions
+10
View File
@@ -1,3 +1,13 @@
2025-08-15 Version 1.1
Library:
* add: bsddialog_slider().
Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/7
Utility:
* add: --slider dialog.
Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/7
2025-06-22 Version 1.0.5 2025-06-22 Version 1.0.5
Manual: Manual:
+1 -1
View File
@@ -4,7 +4,7 @@
# Written in 2023 by Alfonso Sabato Siciliano # Written in 2023 by Alfonso Sabato Siciliano
OUTPUT = bsddialog OUTPUT = bsddialog
export VERSION=1.0.5 export VERSION=1.1
.CURDIR ?= ${CURDIR} .CURDIR ?= ${CURDIR}
LIBPATH = ${.CURDIR}/lib LIBPATH = ${.CURDIR}/lib
LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so
+5 -2
View File
@@ -1,4 +1,4 @@
# BSDDialog 1.0.5 # BSDDialog 1.1
This project provides **bsddialog** and **libbsddialog**, an utility This project provides **bsddialog** and **libbsddialog**, an utility
and a library to build scripts and tools with TUI dialogs and widgets. and a library to build scripts and tools with TUI dialogs and widgets.
@@ -31,7 +31,8 @@ Output:
--calendar, --checklist, --datebox, --form, --gauge, --infobox, --inputbox, --calendar, --checklist, --datebox, --form, --gauge, --infobox, --inputbox,
--menu, --mixedform, --mixedgauge, --msgbox, --passwordbox, --passwordform, --menu, --mixedform, --mixedgauge, --msgbox, --passwordbox, --passwordform,
--pause, --radiolist, --rangebox, --textbox, --timebox, --treeview, --yesno. --pause, --radiolist, --rangebox, --slider, --textbox, --timebox, --treeview,
--yesno.
**Manual** **Manual**
@@ -69,6 +70,7 @@ in the _Public Domain_ to build new projects:
% sh ./examples_utility/pause.sh % sh ./examples_utility/pause.sh
% sh ./examples_utility/radiolist.sh % sh ./examples_utility/radiolist.sh
% sh ./examples_utility/rangebox.sh % sh ./examples_utility/rangebox.sh
% sh ./examples_utility/slider.sh
% sh ./examples_utility/timebox.sh % sh ./examples_utility/timebox.sh
% sh ./examples_utility/yesno.sh % sh ./examples_utility/yesno.sh
``` ```
@@ -106,6 +108,7 @@ in the _Public Domain_ to build new projects:
% ./pause % ./pause
% ./radiolist % ./radiolist
% ./rangebox % ./rangebox
% ./slider
% ./theme % ./theme
% ./timebox % ./timebox
% ./yesno % ./yesno
+1 -1
View File
@@ -12,7 +12,7 @@ set -x
libpath=../lib libpath=../lib
examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \ examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
datebox form timebox rangebox pause calendar gauge mixedgauge textbox" datebox form timebox rangebox pause calendar gauge mixedgauge textbox slider"
rm -f $examples rm -f $examples
+44
View File
@@ -0,0 +1,44 @@
/*-
* SPDX-License-Identifier: CC0-1.0
*
* Written in 2025 by Alfonso Sabato Siciliano.
* To the extent possible under law, the author has dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty, see:
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <bsddialog.h>
#include <stdio.h>
int main()
{
int output;
unsigned long start, end, blocks[2][2];
struct bsddialog_conf conf;
start = 20;
end = 70;
blocks[0][0] = 5;
blocks[0][1] = 10;
blocks[1][0] = 80;
blocks[1][1] = 90;
if (bsddialog_init() == BSDDIALOG_ERROR) {
printf("Error: %s\n", bsddialog_geterror());
return (1);
}
bsddialog_initconf(&conf);
conf.title = "slider";
output = bsddialog_slider(&conf, "Example", 0, 0, "GiB", 100, &start,
&end, false, 2, blocks);
bsddialog_end();
if (output == BSDDIALOG_ERROR) {
printf("Error: %s\n", bsddialog_geterror());
return (1);
}
printf("Start: %lu, End: %lu\n", start, end);
return (0);
}
+34
View File
@@ -0,0 +1,34 @@
#!/bin/sh
#-
# SPDX-License-Identifier: CC0-1.0
#
# Written in 2025 by Braulio Rivas.
#
# To the extent possible under law, the author has dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty, see:
# <http://creativecommons.org/publicdomain/zero/1.0/>.
: ${BSDDIALOG_ERROR=255}
: ${BSDDIALOG_OK=0}
: ${BSDDIALOG_CANCEL=1}
: ${BSDDIALOG_ESC=5}
STARTEND=$(./bsddialog --slider "Choose a new partition location" 0 0 MiB \
30000 5000 6000 0 1000 3000 25000 30000 \
3>&1 1>&2 2>&3 3>&-)
case $? in
$BSDDIALOG_ERROR )
exit 1
;;
$BSDDIALOG_ESC )
echo "[ESC]"
;;
$BSDDIALOG_CANCEL )
echo "[Cancel]"
;;
$BSDDIALOG_OK )
echo "[OK] $STARTEND"
;;
esac
+1 -1
View File
@@ -8,7 +8,7 @@ LIBRARY_SO = lib${LIBRARY:=.so}
LIBRARY_A = lib${LIBRARY:=.a} LIBRARY_A = lib${LIBRARY:=.a}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \ SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \
menubox.c messagebox.c textbox.c theme.c timebox.c menubox.c messagebox.c slider.c textbox.c theme.c timebox.c
OBJECTS = ${SOURCES:.c=.o} OBJECTS = ${SOURCES:.c=.o}
PREFIX = /usr/local PREFIX = /usr/local
+7 -1
View File
@@ -30,7 +30,7 @@
#include <stdbool.h> #include <stdbool.h>
#define LIBBSDDIALOG_VERSION "1.0.5" #define LIBBSDDIALOG_VERSION "1.1"
/* Return values */ /* Return values */
#define BSDDIALOG_ERROR -1 #define BSDDIALOG_ERROR -1
@@ -244,6 +244,12 @@ int
bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows, bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
int cols, int min, int max, int *value); int cols, int min, int max, int *value);
int
bsddialog_slider(struct bsddialog_conf *conf, const char *text, int rows,
int cols, const char *unit, unsigned long length, unsigned long *start,
unsigned long *end, bool resize, unsigned int nblocks,
unsigned long blocks[][2]);
int int
bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows, bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
int cols); int cols);
+670
View File
@@ -0,0 +1,670 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Braulio Rivas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include "bsddialog.h"
#include "bsddialog_theme.h"
#include "lib_util.h"
#define MINHSLIDER 13
#define MINWSLIDER 36
#define NULLWIN -1
#define START_WIN 0
#define END_WIN 1
#define STEP_WIN 2
#define SLIDER_WIN 3
#define NWIN 4
enum operation {
MOVERIGHT,
MOVEFARRIGHT,
MOVEFASTRIGHT,
MOVELEFT,
MOVEFARLEFT,
MOVEFASTLEFT,
INCREASELEFT,
DECREASELEFT,
INCREASERIGHT,
DECREASERIGHT,
INCREASESTEP,
DECREASESTEP,
};
struct sliderctl {
enum operation op;
unsigned long (*spaces)[2];
int nspaces; /* api unsigned, but segfault handlesliderctl():MOVELEFT */
unsigned long length;
unsigned long *start;
unsigned long *end;
unsigned long step;
};
static int crashes(long x, long y, long a, long b)
{
return ((x <= a && a <= y) || (x <= b && b <= y));
}
static int fits(long x, long y, long a, long b)
{
return ((x <= a) && (b <= y));
}
static void handlesliderctl(struct sliderctl *sliderctl)
{
int i, step, tmpstep;
unsigned long x, y, size, old_start, old_end;
signed long new_start, new_end;
step = sliderctl->step;
old_start = *(sliderctl->start);
new_start = old_start;
old_end = *(sliderctl->end);
new_end = old_end;
size = old_end - old_start + 1;
switch (sliderctl->op) {
case MOVERIGHT:
new_start = old_start + step;
new_end = old_end + step;
for (i = 0; i < sliderctl->nspaces; i++) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_start = y + 1;
new_end = new_start + size - 1;
break;
}
}
break;
case MOVELEFT:
new_start = old_start - step;
new_end = old_end - step;
for (i = sliderctl->nspaces - 1; i >= 0; i--) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_end = x - 1;
new_start = new_end - size + 1;
break;
}
}
break;
case INCREASELEFT:
new_start = old_start + step;
break;
case DECREASELEFT:
new_start = old_start - step;
for (i = 0; i < sliderctl->nspaces; i++) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_start = old_start;
break;
}
}
break;
case INCREASERIGHT:
new_end = old_end + step;
for (i = 0; i < sliderctl->nspaces; i++) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_end = old_end;
break;
}
}
break;
case DECREASERIGHT:
new_end = old_end - step;
break;
case MOVEFARLEFT:
new_start = 0;
new_end = size - 1;
for (i = 0; i < sliderctl->nspaces; i++) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_start = y + 1;
new_end = new_start + size - 1;
break;
}
}
break;
case MOVEFARRIGHT:
new_end = (sliderctl->length) - 1;
new_start = new_end - size + 1;
for (i = sliderctl->nspaces - 1; i >= 0; i--) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_end = x - 1;
new_start = new_end - size + 1;
break;
}
}
break;
case MOVEFASTLEFT:
if (size < 10) {
tmpstep = 1;
} else {
tmpstep = ((sliderctl->length) * 10) / 100;
}
new_start = old_start - tmpstep;
new_end = old_end - tmpstep;
for (i = sliderctl->nspaces - 1; i >= 0; i--) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_end = x - 1;
new_start = new_end - size + 1;
break;
}
}
break;
case MOVEFASTRIGHT:
if (size < 10) {
tmpstep = 1;
} else {
tmpstep = ((sliderctl->length) * 10) / 100;
}
new_start = old_start + tmpstep;
new_end = old_end + tmpstep;
for (i = 0; i < sliderctl->nspaces; i++) {
x = (sliderctl->spaces)[i][0];
y = (sliderctl->spaces)[i][1];
if (crashes(x, y, new_start, new_end)) {
new_start = y + 1;
new_end = new_start + size - 1;
break;
}
}
break;
case INCREASESTEP:
++step;
break;
case DECREASESTEP:
if (step > 1) {
--step;
}
break;
}
if (fits(0, (sliderctl->length) - 1, new_start, new_end) != 1) {
new_start = old_start;
new_end = old_end;
}
if (new_start > new_end) {
new_start = old_start;
new_end = old_end;
}
sliderctl->step = step;
*(sliderctl->start) = new_start;
*(sliderctl->end) = new_end;
}
static void
drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev,
bool focus, const char *fmt, unsigned long value)
{
int h, l, w;
getmaxyx(win, h, w);
draw_borders(conf, win, elev);
if (focus) {
l = 2 + w % 2;
wattron(win, t.dialog.arrowcolor);
mvwhline(win, 0, w / 2 - l / 2, UARROW(conf), l);
mvwhline(win, h - 1, w / 2 - l / 2, DARROW(conf), l);
wattroff(win, t.dialog.arrowcolor);
}
if (focus)
wattron(win, t.menu.f_namecolor);
mvwprintw(win, 1, 1, fmt, value);
if (focus)
wattroff(win, t.menu.f_namecolor);
wnoutrefresh(win);
}
static void
print_slider(struct bsddialog_conf *conf, WINDOW *win,
unsigned long spaces[][2], int nspaces, unsigned long length,
unsigned long *start, unsigned long *end, bool active)
{
int i, y, x, l, height, width;
unsigned long s, e;
chtype ch;
getmaxyx(win, height, width);
wclear(win);
draw_borders(conf, win, RAISED);
if (active) {
wattron(win, t.dialog.arrowcolor);
mvwvline(win, 1, 0, LARROW(conf), 1);
mvwvline(win, 1, width - 1, RARROW(conf), 1);
wattroff(win, t.dialog.arrowcolor);
}
y = height / 2;
width -= 1;
ch = ' ' | bsddialog_color(BSDDIALOG_RED, BSDDIALOG_RED, 0);
for (i = 0; i < nspaces; i++) {
s = spaces[i][0];
e = spaces[i][1];
x = (s * width) / length;
l = ((e - s) * width) / length;
if ((e - s) == 0) {
l = 0;
} else if (l == 0) {
l = 1;
}
mvwhline(win, y, x + 1, ch, l);
}
ch = ' ' | t.bar.f_color;
s = ((*start) * width) / length;
l = (((*end) - (*start)) * width) / length;
if ((*end - *start) == 0) {
l = 0;
} else if (l == 0) {
l = 1;
}
mvwhline(win, y, s + 1, ch, l);
wnoutrefresh(win);
}
static int
slider_draw(struct dialog *d, bool redraw, WINDOW *start_win, WINDOW *end_win,
WINDOW *size_win, WINDOW *step_win, WINDOW *slider_win, const char *unit)
{
char *buf;
int yslider, xslider;
if (redraw) {
hide_dialog(d);
refresh(); /* Important for decreasing screen */
}
if (dialog_size_position(d, MINHSLIDER, MINWSLIDER, NULL) != 0)
return (BSDDIALOG_ERROR);
if (draw_dialog(d) != 0) /* doupdate in main loop */
return (BSDDIALOG_ERROR);
if (redraw)
refresh(); /* Important to fix grey lines expanding screen */
TEXTPAD(d, MINHSLIDER + HBUTTONS);
yslider = d->y + d->h - 15;
xslider = d->x + d->w / 2 - 17;
asprintf(&buf, "Start (%s)", unit);
mvwaddstr(d->widget, d->h - 16, d->w / 2 - 17, buf);
free(buf);
update_box(d->conf, start_win, yslider, xslider, 3, 17, RAISED);
asprintf(&buf, "End (%s)", unit);
mvwaddstr(d->widget, d->h - 16, d->w / 2, buf);
free(buf);
update_box(d->conf, end_win, yslider, xslider + 17, 3, 17, RAISED);
asprintf(&buf, "Size (%s)", unit);
mvwaddstr(d->widget, d->h - 12, d->w / 2 - 17, buf);
free(buf);
update_box(d->conf, size_win, yslider + 4, xslider, 3, 17, RAISED);
asprintf(&buf, "Step (%s)", unit);
mvwaddstr(d->widget, d->h - 12, d->w / 2, buf);
free(buf);
update_box(d->conf, step_win, yslider + 4, xslider + 17, 3, 17, RAISED);
update_box(d->conf, slider_win, yslider + 7, xslider, 3, 34, RAISED);
wnoutrefresh(d->widget);
return (0);
}
/* API */
int
bsddialog_slider(struct bsddialog_conf *conf, const char *text, int rows,
int cols, const char *unit, unsigned long length, unsigned long *start,
unsigned long *end, bool resize, unsigned int nblocks,
unsigned long blocks[][2])
{
struct sliderctl ctl;
bool loop, focusbuttons;
int retval, sel;
wint_t input;
unsigned long size;
WINDOW *start_win, *end_win, *size_win, *step_win, *slider_win;
struct dialog dialog;
CHECK_PTR(start);
CHECK_PTR(end);
ctl.spaces = blocks;
ctl.nspaces = nblocks;
ctl.length = length;
ctl.start = start;
ctl.end = end;
ctl.step = 1;
if (prepare_dialog(conf, text, rows, cols, &dialog) != 0)
return (BSDDIALOG_ERROR);
set_buttons(&dialog, true, OK_LABEL, CANCEL_LABEL);
if ((start_win = newwin(1, 1, 1, 1)) == NULL)
RETURN_ERROR("Cannot build WINDOW for start");
wbkgd(start_win, t.dialog.color);
if ((end_win = newwin(1, 1, 1, 1)) == NULL)
RETURN_ERROR("Cannot build WINDOW for end");
wbkgd(end_win, t.dialog.color);
if ((step_win = newwin(1, 1, 1, 1)) == NULL)
RETURN_ERROR("Cannot build WINDOW for step");
wbkgd(step_win, t.dialog.color);
if ((size_win = newwin(1, 1, 1, 1)) == NULL)
RETURN_ERROR("Cannot build WINDOW for size");
wbkgd(size_win, t.dialog.color);
if ((slider_win = newwin(1, 1, 1, 1)) == NULL)
RETURN_ERROR("Cannot build WINDOW for slider");
wbkgd(slider_win, t.dialog.color);
if (slider_draw(&dialog, false, start_win, end_win, size_win, step_win,
slider_win, unit) != 0)
return (BSDDIALOG_ERROR);
sel = NULLWIN;
loop = focusbuttons = true;
while (loop) {
size = *(ctl.end) - *(ctl.start) + 1;
drawsquare(conf, start_win, RAISED, sel == START_WIN, "%15lu", *start);
drawsquare(conf, end_win, RAISED, sel == END_WIN, "%15lu", *end);
drawsquare(conf, size_win, RAISED, 0, "%15lu", size);
drawsquare(conf, step_win, RAISED, sel == STEP_WIN, "%15d", ctl.step);
print_slider(conf, slider_win, blocks, nblocks, length, start,
end, sel == SLIDER_WIN);
doupdate();
if (get_wch(&input) == ERR)
continue;
switch (input) {
case KEY_ENTER:
case 10: /* Enter */
if (focusbuttons || conf->button.always_active) {
retval = BUTTONVALUE(dialog.bs);
loop = false;
}
break;
case 27: /* Esc */
if (conf->key.enable_esc) {
retval = BSDDIALOG_ESC;
loop = false;
}
break;
case '\t': /* TAB */
if (focusbuttons) {
dialog.bs.curr++;
if (dialog.bs.curr >= (int)dialog.bs.nbuttons) {
focusbuttons = false;
sel = START_WIN;
dialog.bs.curr =
conf->button.always_active ? 0 : -1;
}
} else {
sel++;
if ((sel + 1) > NWIN) {
focusbuttons = true;
sel = NULLWIN;
dialog.bs.curr = 0;
}
}
DRAW_BUTTONS(dialog);
break;
case KEY_CTRL('n'):
case KEY_RIGHT:
if (focusbuttons) {
dialog.bs.curr++;
if (dialog.bs.curr >= (int)dialog.bs.nbuttons) {
focusbuttons = false;
sel = START_WIN;
dialog.bs.curr =
conf->button.always_active ? 0 : -1;
}
} else if (sel == SLIDER_WIN) {
ctl.op = MOVERIGHT;
handlesliderctl(&ctl);
} else {
sel++;
}
DRAW_BUTTONS(dialog);
break;
case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
dialog.bs.curr--;
if (dialog.bs.curr < 0) {
focusbuttons = false;
sel = SLIDER_WIN;
dialog.bs.curr =
conf->button.always_active ? 0 : -1;
}
} else if (sel == SLIDER_WIN) {
ctl.op = MOVELEFT;
handlesliderctl(&ctl);
} else if (sel == END_WIN) {
sel = START_WIN;
} else {
focusbuttons = true;
sel = NULLWIN;
dialog.bs.curr = 0;
}
DRAW_BUTTONS(dialog);
break;
case KEY_UP:
if (focusbuttons) {
sel = SLIDER_WIN;
focusbuttons = false;
dialog.bs.curr =
conf->button.always_active ? 0 : -1;
DRAW_BUTTONS(dialog);
} else if (sel == START_WIN) {
if (resize) {
ctl.op = INCREASELEFT;
} else {
ctl.op = MOVERIGHT;
}
handlesliderctl(&ctl);
} else if (sel == END_WIN) {
if (resize) {
ctl.op = INCREASERIGHT;
} else {
ctl.op = MOVERIGHT;
}
handlesliderctl(&ctl);
} else if (sel == STEP_WIN) {
ctl.op = INCREASESTEP;
handlesliderctl(&ctl);
}
break;
case KEY_DOWN:
if (focusbuttons) {
break;
} else if (sel == START_WIN) {
if (resize) {
ctl.op = DECREASELEFT;
} else {
ctl.op = MOVELEFT;
}
handlesliderctl(&ctl);
} else if (sel == END_WIN) {
if (resize) {
ctl.op = DECREASERIGHT;
} else {
ctl.op = MOVELEFT;
}
handlesliderctl(&ctl);
} else if (sel == STEP_WIN) {
ctl.op = DECREASESTEP;
handlesliderctl(&ctl);
}
break;
case '-':
if (focusbuttons) {
break;
} else if (sel == START_WIN) {
if (resize) {
ctl.op = DECREASELEFT;
} else {
ctl.op = MOVELEFT;
}
handlesliderctl(&ctl);
} else if (sel == END_WIN) {
if (resize) {
ctl.op = DECREASERIGHT;
} else {
ctl.op = MOVELEFT;
}
handlesliderctl(&ctl);
} else if (sel == STEP_WIN) {
ctl.op = DECREASESTEP;
handlesliderctl(&ctl);
}
break;
case '+':
if (focusbuttons) {
break;
} else if (sel == START_WIN) {
if (resize) {
ctl.op = INCREASELEFT;
} else {
ctl.op = MOVERIGHT;
}
handlesliderctl(&ctl);
} else if (sel == END_WIN) {
if (resize) {
ctl.op = INCREASERIGHT;
} else {
ctl.op = MOVERIGHT;
}
handlesliderctl(&ctl);
} else if (sel == STEP_WIN) {
ctl.op = INCREASESTEP;
handlesliderctl(&ctl);
}
break;
case KEY_HOME:
if (focusbuttons) {
break;
} else if (sel == SLIDER_WIN) {
ctl.op = MOVEFARLEFT;
handlesliderctl(&ctl);
}
break;
case KEY_END:
if (focusbuttons) {
break;
} else if (sel == SLIDER_WIN) {
ctl.op = MOVEFARRIGHT;
handlesliderctl(&ctl);
}
break;
case KEY_PPAGE:
if (focusbuttons) {
break;
} else if (sel == SLIDER_WIN) {
ctl.op = MOVEFASTLEFT;
handlesliderctl(&ctl);
}
break;
case KEY_NPAGE:
if (focusbuttons) {
break;
} else if (sel == SLIDER_WIN) {
ctl.op = MOVEFASTRIGHT;
handlesliderctl(&ctl);
}
break;
case KEY_F(1):
if (conf->key.f1_file == NULL &&
conf->key.f1_message == NULL)
break;
if (f1help_dialog(conf) != 0)
return (BSDDIALOG_ERROR);
if (slider_draw(&dialog, true, start_win, end_win, size_win,
step_win, slider_win, unit) != 0)
return (BSDDIALOG_ERROR);
break;
case KEY_CTRL('l'):
case KEY_RESIZE:
if (slider_draw(&dialog, true, start_win, end_win, size_win,
step_win, slider_win, unit) != 0)
return (BSDDIALOG_ERROR);
break;
default:
if (shortcut_buttons(input, &dialog.bs)) {
DRAW_BUTTONS(dialog);
doupdate();
retval = BUTTONVALUE(dialog.bs);
loop = false;
}
}
}
delwin(start_win);
delwin(end_win);
delwin(step_win);
delwin(slider_win);
end_dialog(&dialog);
return (retval);
}
+5 -1
View File
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd June 22, 2025 .Dd June 24, 2025
.Dt BSDDIALOG 1 .Dt BSDDIALOG 1
.Os .Os
.Sh NAME .Sh NAME
@@ -851,6 +851,10 @@ utility first appeared in
was written by was written by
.An Alfonso Sabato Siciliano .An Alfonso Sabato Siciliano
.Aq Mt asiciliano@FreeBSD.org . .Aq Mt asiciliano@FreeBSD.org .
.An Braulio Rivas
.Aq Mt brauliorivas@FreeBSD.org
implemented the slider dialog for the
.Dq GSoC 2025 Full Disk Administration Tool for FreeBSD .
.Pp .Pp
.Nm bsddialog .Nm bsddialog
provides also a subset of the functionality described in the provides also a subset of the functionality described in the
+1
View File
@@ -108,6 +108,7 @@ int passwordform_builder(BUILDER_ARGS);
int pause_builder(BUILDER_ARGS); int pause_builder(BUILDER_ARGS);
int radiolist_builder(BUILDER_ARGS); int radiolist_builder(BUILDER_ARGS);
int rangebox_builder(BUILDER_ARGS); int rangebox_builder(BUILDER_ARGS);
int slider_builder(BUILDER_ARGS);
int textbox_builder(BUILDER_ARGS); int textbox_builder(BUILDER_ARGS);
int timebox_builder(BUILDER_ARGS); int timebox_builder(BUILDER_ARGS);
int treeview_builder(BUILDER_ARGS); int treeview_builder(BUILDER_ARGS);
+38
View File
@@ -809,3 +809,41 @@ int passwordform_builder(BUILDER_ARGS)
return (output); return (output);
} }
int slider_builder(BUILDER_ARGS)
{
bool resize;
int output;
char *unit;
unsigned int i, nblocks;
unsigned long length, start, end, (*blocks)[2];
if (argc < 5)
exit_error(true, "--slider requires: <unit> <lenght> <start> <end> <resize>");
unit = argv[0];
length = strtoul(argv[1], NULL, 10);
start = strtoul(argv[2], NULL, 10);
end = strtoul(argv[3], NULL, 10);
resize = strtoul(argv[4], NULL, 10) == 0 ? false : true;
argc -= 5;
argv += 5;
if (argc & 1)
exit_error(true, "bad [<start_block> <end_block> ...] number");
nblocks = argc / 2;
if ((blocks = malloc(nblocks * sizeof(*blocks))) == NULL)
exit_error(false, "Cannot allocate memory for blocks");
for (i = 0; i < nblocks; i++) {
blocks[i][0] = strtoul(argv[2 * i], NULL, 10);
blocks[i][1] = strtoul(argv[2 * i + 1], NULL, 10);
}
output = bsddialog_slider(conf, text, rows, cols, unit, length, &start, &end,
resize, nblocks, blocks);
free(blocks);
if (output != BSDDIALOG_ERROR)
dprintf(opt->output_fd, "%lu %lu", start, end);
return (output);
}
+10 -1
View File
@@ -143,7 +143,8 @@ enum OPTS {
TEXTBOX, TEXTBOX,
TIMEBOX, TIMEBOX,
TREEVIEW, TREEVIEW,
YESNO YESNO,
SLIDER,
}; };
/* options descriptor */ /* options descriptor */
@@ -264,6 +265,7 @@ static struct option longopts[] = {
{"pause", no_argument, NULL, PAUSE}, {"pause", no_argument, NULL, PAUSE},
{"radiolist", no_argument, NULL, RADIOLIST}, {"radiolist", no_argument, NULL, RADIOLIST},
{"rangebox", no_argument, NULL, RANGEBOX}, {"rangebox", no_argument, NULL, RANGEBOX},
{"slider", no_argument, NULL, SLIDER},
{"textbox", no_argument, NULL, TEXTBOX}, {"textbox", no_argument, NULL, TEXTBOX},
{"timebox", no_argument, NULL, TIMEBOX}, {"timebox", no_argument, NULL, TIMEBOX},
{"treeview", no_argument, NULL, TREEVIEW}, {"treeview", no_argument, NULL, TREEVIEW},
@@ -801,6 +803,13 @@ parseargs(int argc, char **argv, struct bsddialog_conf *conf,
opt->name = "--rangebox"; opt->name = "--rangebox";
opt->dialogbuilder = rangebox_builder; opt->dialogbuilder = rangebox_builder;
break; break;
case SLIDER:
if (opt->dialogbuilder != NULL)
exit_error(true, "%s and --slider without "
"--and-dialog", opt->name);
opt->name = "--slider";
opt->dialogbuilder = slider_builder;
break;
case TEXTBOX: case TEXTBOX:
if (opt->dialogbuilder != NULL) if (opt->dialogbuilder != NULL)
exit_error(true, "%s and --textbox without " exit_error(true, "%s and --textbox without "