aboutsummaryrefslogtreecommitdiff
path: root/contrib/bsddialog/lib/timebox.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bsddialog/lib/timebox.c')
-rw-r--r--contrib/bsddialog/lib/timebox.c525
1 files changed, 110 insertions, 415 deletions
diff --git a/contrib/bsddialog/lib/timebox.c b/contrib/bsddialog/lib/timebox.c
index 7d69666c32b8..d683f9552b50 100644
--- a/contrib/bsddialog/lib/timebox.c
+++ b/contrib/bsddialog/lib/timebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,512 +25,207 @@
* SUCH DAMAGE.
*/
-#include <sys/param.h>
-
-#include <ctype.h>
#include <curses.h>
-#include <string.h>
#include "bsddialog.h"
+#include "bsddialog_theme.h"
#include "lib_util.h"
-#define MINWDATE 23 /* 3 windows and their borders */
#define MINWTIME 14 /* 3 windows and their borders */
-
-static int
-datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
- int *w, int minw, const char *text, struct buttons bs)
+#define HBOX 3
+#define WBOX 4
+
+struct clock {
+ unsigned int max;
+ unsigned int value;
+ WINDOW *win;
+};
+
+static void
+drawsquare(struct bsddialog_conf *conf, WINDOW *win, unsigned int value,
+ bool focus)
{
- int htext, wtext;
-
- if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
- if (text_size(conf, rows, cols, text, &bs, 3, minw, &htext,
- &wtext) != 0)
- return (BSDDIALOG_ERROR);
+ draw_borders(conf, win, LOWERED);
+ if (focus) {
+ wattron(win, t.dialog.arrowcolor);
+ mvwhline(win, 0, 1, conf->ascii_lines ? '^' : ACS_UARROW, 2);
+ mvwhline(win, 2, 1, conf->ascii_lines ? 'v' : ACS_DARROW, 2);
+ wattroff(win, t.dialog.arrowcolor);
}
- if (cols == BSDDIALOG_AUTOSIZE)
- *w = widget_min_width(conf, htext,minw, &bs);
+ if (focus)
+ wattron(win, t.menu.f_namecolor);
+ mvwprintw(win, 1, 1, "%02u", value);
+ if (focus)
+ wattroff(win, t.menu.f_namecolor);
- if (rows == BSDDIALOG_AUTOSIZE)
- *h = widget_min_height(conf, htext, 3 /* windows */, true);
-
- return (0);
+ wnoutrefresh(win);
}
-static int
-datetime_checksize(int rows, int cols, int minw, struct buttons bs)
+static int timebox_redraw(struct dialog *d, struct clock *c)
{
- int mincols;
+ int y, x;
- mincols = VBORDERS;
- mincols += buttons_width(bs);
- mincols = MAX(minw, mincols);
-
- if (cols < mincols)
- RETURN_ERROR("Few cols for this timebox/datebox");
-
- if (rows < 7) /* 2 button + 2 borders + 3 windows */
- RETURN_ERROR("Few rows for this timebox/datebox, at least 7");
+ if (d->built) {
+ hide_dialog(d);
+ refresh(); /* Important for decreasing screen */
+ }
+ if (dialog_size_position(d, HBOX, MINWTIME, NULL) != 0)
+ return (BSDDIALOG_ERROR);
+ if (draw_dialog(d) != 0)
+ return (BSDDIALOG_ERROR);
+ if (d->built)
+ refresh(); /* Important to fix grey lines expanding screen */
+ TEXTPAD(d, HBOX + HBUTTONS);
+
+ y = d->y + d->h - BORDER - HBUTTONS - HBOX;
+ x = d->x + d->w/2 - 7;
+ update_box(d->conf, c[0].win, y, x, HBOX, WBOX, LOWERED);
+ mvwaddch(d->widget, d->h - 5, d->w/2 - 3, ':');
+ update_box(d->conf, c[1].win, y, x += 5, HBOX, WBOX, LOWERED);
+ mvwaddch(d->widget, d->h - 5, d->w/2 + 2, ':');
+ update_box(d->conf, c[2].win, y, x + 5, HBOX, WBOX, LOWERED);
+ wnoutrefresh(d->widget); /* for mvwaddch(':') */
return (0);
}
+/* API */
int
bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss)
{
bool loop, focusbuttons;
- int i, input, output, y, x, h, w, sel;
- WINDOW *widget, *textpad, *shadow;
- struct buttons bs;
- struct myclockstruct {
- unsigned int max;
- unsigned int value;
- WINDOW *win;
- };
-
- if (hh == NULL || mm == NULL || ss == NULL)
- RETURN_ERROR("hh / mm / ss cannot be NULL");
-
- struct myclockstruct c[3] = {
+ int i, retval, sel;
+ wint_t input;
+ struct dialog d;
+ struct clock c[3] = {
{23, *hh, NULL},
{59, *mm, NULL},
{59, *ss, NULL}
};
- for (i = 0 ; i < 3; i++) {
- if (c[i].value > c[i].max)
- c[i].value = c[i].max;
- }
-
- get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text,
- bs) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_checksize(h, w, MINWTIME, bs) != 0)
+ CHECK_PTR(hh);
+ CHECK_PTR(mm);
+ CHECK_PTR(ss);
+ if (prepare_dialog(conf, text, rows, cols, &d) != 0)
return (BSDDIALOG_ERROR);
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return (BSDDIALOG_ERROR);
-
- if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
- true) != 0)
+ set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
+ for (i=0; i<3; i++) {
+ if ((c[i].win = newwin(1, 1, 1, 1)) == NULL)
+ RETURN_FMTERROR("Cannot build WINDOW for time[%d]", i);
+ wbkgd(c[i].win, t.dialog.color);
+ c[i].value = MIN(c[i].value, c[i].max);
+ }
+ if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
- pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
- doupdate();
-
- c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 7, 3, 4, LOWERED);
- mvwaddch(widget, h - 5, w/2 - 3, ':');
- c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 2, 3, 4, LOWERED);
- mvwaddch(widget, h - 5, w/2 + 2, ':');
- c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 3, 3, 4, LOWERED);
-
- wrefresh(widget);
-
+ sel = -1;
loop = focusbuttons = true;
while (loop) {
- for (i = 0; i < 3; i++) {
- mvwprintw(c[i].win, 1, 1, "%2d", c[i].value);
- wrefresh(c[i].win);
- }
-
- if (focusbuttons == false) {
- wmove(c[sel].win, 1, 2);
- wrefresh(c[sel].win);
- }
-
- input = getch();
+ for (i = 0; i < 3; i++)
+ drawsquare(conf, c[i].win, c[i].value, sel == i);
+ doupdate();
+ if (get_wch(&input) == ERR)
+ continue;
switch(input) {
case KEY_ENTER:
case 10: /* Enter */
- if (focusbuttons == false)
- break;
- output = bs.value[bs.curr];
- loop = false;
+ if (focusbuttons || conf->button.always_active) {
+ retval = BUTTONVALUE(d.bs);
+ loop = false;
+ }
break;
case 27: /* Esc */
if (conf->key.enable_esc) {
- output = BSDDIALOG_ESC;
+ retval = BSDDIALOG_ESC;
loop = false;
}
break;
case KEY_RIGHT:
case '\t': /* TAB */
if (focusbuttons) {
- bs.curr++;
- focusbuttons = bs.curr < (int)bs.nbuttons ?
+ d.bs.curr++;
+ focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
true : false;
if (focusbuttons == false) {
- curs_set(1);
sel = 0;
+ d.bs.curr =
+ conf->button.always_active ? 0 : -1;
}
} else {
sel++;
focusbuttons = sel > 2 ? true : false;
if (focusbuttons) {
- curs_set(0);
- bs.curr = 0;
+ d.bs.curr = 0;
}
}
- draw_buttons(widget, bs, true);
- wrefresh(widget);
+ DRAW_BUTTONS(d);
break;
case KEY_LEFT:
if (focusbuttons) {
- bs.curr--;
- focusbuttons = bs.curr < 0 ? false : true;
+ d.bs.curr--;
+ focusbuttons = d.bs.curr < 0 ? false : true;
if (focusbuttons == false) {
- curs_set(1);
sel = 2;
+ d.bs.curr =
+ conf->button.always_active ? 0 : -1;
}
} else {
sel--;
focusbuttons = sel < 0 ? true : false;
- if (focusbuttons) {
- curs_set(0);
- bs.curr = (int)bs.nbuttons - 1;
- }
+ if (focusbuttons)
+ d.bs.curr = (int)d.bs.nbuttons - 1;
}
- draw_buttons(widget, bs, true);
- wrefresh(widget);
+ DRAW_BUTTONS(d);
break;
case KEY_UP:
- if (focusbuttons)
- break;
- c[sel].value = c[sel].value > 0 ?
- c[sel].value - 1 : c[sel].max;
- break;
- case KEY_DOWN:
- if (focusbuttons)
- break;
- c[sel].value = c[sel].value < c[sel].max ?
- c[sel].value + 1 : 0;
- break;
- case KEY_F(1):
- if (conf->key.f1_file == NULL &&
- conf->key.f1_message == NULL)
- break;
- curs_set(0);
- if (f1help(conf) != 0)
- return (BSDDIALOG_ERROR);
- curs_set(1);
- /* No break, screen size can change */
- case KEY_RESIZE:
- /* Important for decreasing screen */
- hide_widget(y, x, h, w, conf->shadow);
- refresh();
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_autosize(conf, rows, cols, &h, &w,
- MINWTIME, text, bs) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_checksize(h, w, MINWTIME, bs) != 0)
- return (BSDDIALOG_ERROR);
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return (BSDDIALOG_ERROR);
-
- if (update_dialog(conf, shadow, widget, y, x, h, w,
- textpad, text, &bs, true) != 0)
- return (BSDDIALOG_ERROR);
-
- doupdate();
-
- mvwaddch(widget, h - 5, w/2 - 3, ':');
- mvwaddch(widget, h - 5, w/2 + 2, ':');
- wrefresh(widget);
-
- prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
-
- wclear(c[0].win);
- mvwin(c[0].win, y + h - 6, x + w/2 - 7);
- draw_borders(conf, c[0].win, 3, 4, LOWERED);
- wrefresh(c[0].win);
-
- wclear(c[1].win);
- mvwin(c[1].win, y + h - 6, x + w/2 - 2);
- draw_borders(conf, c[1].win, 3, 4, LOWERED);
- wrefresh(c[1].win);
-
- wclear(c[2].win);
- mvwin(c[2].win, y + h - 6, x + w/2 + 3);
- draw_borders(conf, c[2].win, 3, 4, LOWERED);
- wrefresh(c[2].win);
-
- /* Important to avoid grey lines expanding screen */
- refresh();
- break;
- default:
- if (shortcut_buttons(input, &bs)) {
- output = bs.value[bs.curr];
- loop = false;
- }
- }
- }
-
- if (output == BSDDIALOG_OK) {
- *hh = c[0].value;
- *mm = c[1].value;
- *ss = c[2].value;
- }
-
- curs_set(0);
-
- for (i = 0; i < 3; i++)
- delwin(c[i].win);
- end_dialog(conf, shadow, widget, textpad);
-
- return (output);
-}
-
-int
-bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
- int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd)
-{
- bool loop, focusbuttons;
- int i, input, output, y, x, h, w, sel;
- WINDOW *widget, *textpad, *shadow;
- struct buttons bs;
- struct calendar {
- int max;
- int value;
- WINDOW *win;
- unsigned int x;
- };
- struct month {
- const char *name;
- unsigned int days;
- };
-
- if (yy == NULL || mm == NULL || dd == NULL)
- RETURN_ERROR("yy / mm / dd cannot be NULL");
-
- struct calendar c[3] = {
- {9999, *yy, NULL, 4 },
- {12, *mm, NULL, 9 },
- {31, *dd, NULL, 2 }
- };
-
- struct month m[12] = {
- { "January", 31 }, { "February", 28 }, { "March", 31 },
- { "April", 30 }, { "May", 31 }, { "June", 30 },
- { "July", 31 }, { "August", 31 }, { "September", 30 },
- { "October", 31 }, { "November", 30 }, { "December", 31 }
- };
-
-#define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
-
- for (i = 0 ; i < 3; i++) {
- if (c[i].value > c[i].max)
- c[i].value = c[i].max;
- if (c[i].value < 1)
- c[i].value = 1;
- }
- c[2].max = m[c[1].value -1].days;
- if (c[1].value == 2 && ISLEAF(c[0].value))
- c[2].max = 29;
- if (c[2].value > c[2].max)
- c[2].value = c[2].max;
-
- get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text,
- bs) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_checksize(h, w, MINWDATE, bs) != 0)
- return (BSDDIALOG_ERROR);
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return (BSDDIALOG_ERROR);
-
- if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
- true) != 0)
- return (BSDDIALOG_ERROR);
-
- pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
- doupdate();
-
- c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 11, 3, 6, LOWERED);
- mvwaddch(widget, h - 5, w/2 - 5, '/');
- c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 4, 3, 11, LOWERED);
- mvwaddch(widget, h - 5, w/2 + 7, '/');
- c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 8, 3, 4, LOWERED);
-
- wrefresh(widget);
-
- loop = focusbuttons = true;
- while (loop) {
- mvwprintw(c[0].win, 1, 1, "%4d", c[0].value);
- mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name);
- mvwprintw(c[2].win, 1, 1, "%2d", c[2].value);
- for (i = 0; i < 3; i++) {
- wrefresh(c[i].win);
- }
- if (focusbuttons == false) {
- wmove(c[sel].win, 1, c[sel].x);
- wrefresh(c[sel].win);
- }
-
- input = getch();
- switch(input) {
- case KEY_ENTER:
- case 10: /* Enter */
- if (focusbuttons == false)
- break;
- output = bs.value[bs.curr];
- loop = false;
- break;
- case 27: /* Esc */
- if (conf->key.enable_esc) {
- output = BSDDIALOG_ESC;
- loop = false;
- }
- break;
- case KEY_RIGHT:
- case '\t': /* TAB */
- if (focusbuttons) {
- bs.curr++;
- focusbuttons = bs.curr < (int)bs.nbuttons ?
- true : false;
- if (focusbuttons == false) {
- curs_set(1);
- sel = 0;
- }
- } else {
- sel++;
- focusbuttons = sel > 2 ? true : false;
- if (focusbuttons) {
- curs_set(0);
- bs.curr = 0;
- }
- }
- draw_buttons(widget, bs, true);
- wrefresh(widget);
- break;
- case KEY_LEFT:
if (focusbuttons) {
- bs.curr--;
- focusbuttons = bs.curr < 0 ? false : true;
- if (focusbuttons == false) {
- curs_set(1);
- sel = 2;
- }
+ sel = 0;
+ focusbuttons = false;
+ d.bs.curr = conf->button.always_active ? 0 : -1;
+ DRAW_BUTTONS(d);
} else {
- sel--;
- focusbuttons = sel < 0 ? true : false;
- if (focusbuttons) {
- curs_set(0);
- bs.curr = (int)bs.nbuttons - 1;
- }
+ c[sel].value = c[sel].value > 0 ?
+ c[sel].value - 1 : c[sel].max;
}
- draw_buttons(widget, bs, true);
- wrefresh(widget);
- break;
- case KEY_UP:
- if (focusbuttons)
- break;
- c[sel].value = c[sel].value > 1 ?
- c[sel].value - 1 : c[sel].max ;
- /* if mount change */
- c[2].max = m[c[1].value -1].days;
- /* if year change */
- if (c[1].value == 2 && ISLEAF(c[0].value))
- c[2].max = 29;
- /* set new day */
- if (c[2].value > c[2].max)
- c[2].value = c[2].max;
break;
case KEY_DOWN:
if (focusbuttons)
break;
c[sel].value = c[sel].value < c[sel].max ?
- c[sel].value + 1 : 1;
- /* if mount change */
- c[2].max = m[c[1].value -1].days;
- /* if year change */
- if (c[1].value == 2 && ISLEAF(c[0].value))
- c[2].max = 29;
- /* set new day */
- if (c[2].value > c[2].max)
- c[2].value = c[2].max;
+ c[sel].value + 1 : 0;
break;
case KEY_F(1):
if (conf->key.f1_file == NULL &&
conf->key.f1_message == NULL)
break;
- curs_set(0);
- if (f1help(conf) != 0)
- return (BSDDIALOG_ERROR);
- curs_set(1);
- /* No break, screen size can change */
- case KEY_RESIZE:
- /* Important for decreasing screen */
- hide_widget(y, x, h, w, conf->shadow);
- refresh();
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return (BSDDIALOG_ERROR);
- if (datetime_autosize(conf, rows, cols, &h, &w,
- MINWDATE, text, bs) != 0)
+ if (f1help_dialog(conf) != 0)
return (BSDDIALOG_ERROR);
- if (datetime_checksize(h, w, MINWDATE, bs) != 0)
+ if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return (BSDDIALOG_ERROR);
-
- if (update_dialog(conf, shadow, widget, y, x, h, w,
- textpad, text, &bs, true) != 0)
+ break;
+ case KEY_RESIZE:
+ if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
- doupdate();
-
- mvwaddch(widget, h - 5, w/2 - 5, '/');
- mvwaddch(widget, h - 5, w/2 + 7, '/');
- wrefresh(widget);
-
- prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
-
- wclear(c[0].win);
- mvwin(c[0].win, y + h - 6, x + w/2 - 11);
- draw_borders(conf, c[0].win, 3, 6, LOWERED);
- wrefresh(c[0].win);
-
- wclear(c[1].win);
- mvwin(c[1].win, y + h - 6, x + w/2 - 4);
- draw_borders(conf, c[1].win, 3, 11, LOWERED);
- wrefresh(c[1].win);
-
- wclear(c[2].win);
- mvwin(c[2].win, y + h - 6, x + w/2 + 8);
- draw_borders(conf, c[2].win, 3, 4, LOWERED);
- wrefresh(c[2].win);
-
- /* Important to avoid grey lines expanding screen */
- refresh();
break;
default:
- if (shortcut_buttons(input, &bs)) {
- output = bs.value[bs.curr];
+ if (shortcut_buttons(input, &d.bs)) {
+ DRAW_BUTTONS(d);
+ doupdate();
+ retval = BUTTONVALUE(d.bs);
loop = false;
}
}
}
- if (output == BSDDIALOG_OK) {
- *yy = c[0].value;
- *mm = c[1].value;
- *dd = c[2].value;
- }
-
- curs_set(0);
+ *hh = c[0].value;
+ *mm = c[1].value;
+ *ss = c[2].value;
for (i = 0; i < 3; i++)
delwin(c[i].win);
- end_dialog(conf, shadow, widget, textpad);
+ end_dialog(&d);
- return (output);
+ return (retval);
}