aboutsummaryrefslogtreecommitdiff
path: root/lib/messagebox.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/messagebox.c')
-rw-r--r--lib/messagebox.c237
1 files changed, 98 insertions, 139 deletions
diff --git a/lib/messagebox.c b/lib/messagebox.c
index 6fe775cfcbc9..edea7c41c18d 100644
--- a/lib/messagebox.c
+++ b/lib/messagebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,60 +27,34 @@
#include <sys/param.h>
-#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <string.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-#define AUTO_WIDTH (COLS / 3U)
-/* at least 1 line text for its pad building in widget_withtextpad_init() */
-#define MIN_HEIGHT (HBORDERS + 2 /*buttons*/ + 1 /*text*/)
+#include "lib_util.h"
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 *w, const 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.button.space : 0;
- /* text size */
- line = MIN(maxline + VBORDERS + t.text.hmargin * 2, AUTO_WIDTH);
- line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2));
- *w = MAX(*w, line);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf));
- }
+ int htext, wtext;
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = MIN_HEIGHT - 1;
- if (maxword > 0)
- *h += MAX(nlines, (int)(*w / GET_ASPECT_RATIO(conf)));
- *h = MAX(*h, MIN_HEIGHT);
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, 0, SCREENCOLS/2,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- return 0;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, 0, &bs);
+
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, 0, true);
+
+ return (0);
}
static int message_checksize(int rows, int cols, struct buttons bs)
@@ -92,182 +66,167 @@ static int message_checksize(int rows, int cols, struct buttons bs)
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
if (cols < mincols)
- RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "\
+ 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");
+ if (rows < HBORDERS + 2 /*buttons*/)
+ RETURN_ERROR("Msgbox and Yesno need at least height 4");
- return 0;
+ return (0);
}
static void
-buttonsupdate(WINDOW *widget, int h, int w, struct buttons bs)
+textupdate(WINDOW *widget, WINDOW *textpad, int htextpad, int ytextpad)
{
- draw_buttons(widget, h-2, w, bs, true);
- wnoutrefresh(widget);
-}
+ int y, x, h, w;
+
+ getbegyx(widget, y, x);
+ getmaxyx(widget, h, w);
-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);
+ 100 * (ytextpad+h-4)/ htextpad);
wnoutrefresh(widget);
}
- pnoutrefresh(textpad, textrow, 0, y+1, x+2, y+h-4, x+w-2);
+ pnoutrefresh(textpad, ytextpad, 0, y+1, x+2, y+h-4, x+w-2);
}
static int
-do_dialog(struct bsddialog_conf *conf, char *text, int rows, int cols,
+do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
struct buttons bs)
{
- WINDOW *widget, *textpad, *shadow;
bool loop;
- int i, y, x, h, w, input, output, htextpad, textrow;
+ int y, x, h, w, input, output, ytextpad, htextpad, unused;
+ WINDOW *widget, *textpad, *shadow;
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (message_checksize(h, w, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
- textrow = 0;
+ ytextpad = 0;
+ getmaxyx(textpad, htextpad, unused);
+ unused++; /* fix unused error */
+ textupdate(widget, textpad, htextpad, ytextpad);
loop = true;
- buttonsupdate(widget, h, w, bs);
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
- while(loop) {
+ while (loop) {
doupdate();
input = getch();
switch (input) {
+ case KEY_ENTER:
case 10: /* Enter */
output = bs.value[bs.curr];
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
- buttonsupdate(widget, h, w, bs);
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ break;
+ case KEY_LEFT:
+ if (bs.curr > 0) {
+ bs.curr--;
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ }
+ break;
+ case KEY_RIGHT:
+ if (bs.curr < (int)bs.nbuttons - 1) {
+ bs.curr++;
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ }
break;
case KEY_F(1):
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen 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
- */
+ /* 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 (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
- return BSDDIALOG_ERROR;
+ 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;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
-
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
-
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- buttonsupdate(widget, h, w, bs);
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
+ getmaxyx(textpad, htextpad, unused);
+ textupdate(widget, textpad, htextpad, ytextpad);
/* Important to fix grey lines expanding screen */
refresh();
break;
case KEY_UP:
- if (textrow == 0)
+ if (ytextpad == 0)
break;
- textrow--;
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
+ ytextpad--;
+ textupdate(widget, textpad, htextpad, ytextpad);
break;
case KEY_DOWN:
- if (textrow + h - 4 >= htextpad)
+ if (ytextpad + 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);
- }
- break;
- case KEY_RIGHT:
- if (bs.curr < (int) bs.nbuttons - 1) {
- bs.curr++;
- buttonsupdate(widget, h, w, bs);
- }
+ ytextpad++;
+ textupdate(widget, textpad, htextpad, ytextpad);
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower(bs.label[i][0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
+ return (output);
}
/* API */
int
-bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols)
+bsddialog_msgbox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols)
{
struct buttons bs;
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- NULL, BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, NULL);
- return (do_dialog(conf, text, rows, cols, bs));
+ return (do_message(conf, text, rows, cols, bs));
}
int
-bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols)
+bsddialog_yesno(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols)
{
struct buttons bs;
- get_buttons(conf, &bs,
- conf->button.ok_label == NULL ? "Yes" : conf->button.ok_label,
- BUTTONLABEL(extra_label),
- conf->button.cancel_label == NULL ? "No" : conf->button.cancel_label,
- BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, "Yes", "No");
- return (do_dialog(conf, text, rows, cols, bs));
-}
+ return (do_message(conf, text, rows, cols, bs));
+} \ No newline at end of file