aboutsummaryrefslogtreecommitdiff
path: root/lib/lib_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lib_util.c')
-rw-r--r--lib/lib_util.c755
1 files changed, 473 insertions, 282 deletions
diff --git a/lib/lib_util.c b/lib/lib_util.c
index 81c2b7642aac..f7e6a2ae15ab 100644
--- a/lib/lib_util.c
+++ b/lib/lib_util.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,46 +27,42 @@
#include <sys/param.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <ctype.h>
+#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
extern struct bsddialog_theme t;
-/* Error buffer */
+#define TABLEN 4 /* Default tab len */
+#define ERRBUFLEN 1024 /* Error buffer */
-#define ERRBUFLEN 1024
+/* Error */
static char errorbuffer[ERRBUFLEN];
const char *get_error_string(void)
{
- return errorbuffer;
+ return (errorbuffer);
}
void set_error_string(char *str)
{
-
strncpy(errorbuffer, str, ERRBUFLEN-1);
}
-/* cleaner */
+/* Clear */
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.shadow.h, x + t.shadow.w)) == NULL)
RETURN_ERROR("Cannot hide the widget");
- wbkgd(clear, t.terminal.color);
+ wbkgd(clear, t.screen.color);
if (withshadow)
wrefresh(clear);
@@ -76,7 +72,7 @@ int hide_widget(int y, int x, int h, int w, bool withshadow)
delwin(clear);
- return 0;
+ return (0);
}
/* F1 help */
@@ -85,15 +81,14 @@ int f1help(struct bsddialog_conf *conf)
int output;
struct bsddialog_conf hconf;
- //memcpy(&hconf, conf, sizeof(struct bsddialog_conf));
bsddialog_initconf(&hconf);
- hconf.title = "HELP";
+ hconf.title = "HELP";
hconf.button.ok_label = "EXIT";
- hconf.clear = true;
- hconf.ascii_lines = conf->ascii_lines;
- hconf.no_lines = conf->no_lines;
- hconf.shadow = conf->shadow;
- hconf.text.colors = conf->text.colors;
+ hconf.clear = true;
+ hconf.ascii_lines = conf->ascii_lines;
+ hconf.no_lines = conf->no_lines;
+ hconf.shadow = conf->shadow;
+ hconf.text.highlight = conf->text.highlight;
output = BSDDIALOG_OK;
if (conf->f1_message != NULL)
@@ -106,9 +101,9 @@ int f1help(struct bsddialog_conf *conf)
}
/* Buttons */
-void
-draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
- bool shortkey)
+static void
+draw_button(WINDOW *window, int y, int x, int size, const char *text,
+ bool selected, bool shortcut)
{
int i, color_arrows, color_shortkey, color_button;
@@ -126,7 +121,7 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
mvwaddch(window, y, x, t.button.leftch);
wattroff(window, color_arrows);
wattron(window, color_button);
- for(i = 1; i < size - 1; i++)
+ for (i = 1; i < size - 1; i++)
waddch(window, ' ');
wattroff(window, color_button);
wattron(window, color_arrows);
@@ -138,7 +133,7 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
mvwaddstr(window, y, x, text);
wattroff(window, color_button);
- if (shortkey) {
+ if (shortcut) {
wattron(window, color_shortkey);
mvwaddch(window, y, x, text[0]);
wattroff(window, color_shortkey);
@@ -146,56 +141,62 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
}
void
-draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey)
+draw_buttons(WINDOW *window, struct buttons bs, bool shortcut)
{
- int i, x, start_x;
+ int i, x, startx, y, rows, cols;
+
+ getmaxyx(window, rows, cols);
+ y = rows - 2;
- start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.button.space;
- start_x = cols/2 - start_x/2;
+ startx = bs.sizebutton * bs.nbuttons + (bs.nbuttons-1) * t.button.space;
+ startx = cols/2 - startx/2;
for (i = 0; i < (int) bs.nbuttons; i++) {
x = i * (bs.sizebutton + t.button.space);
- draw_button(window, y, start_x + x, bs.sizebutton, bs.label[i],
- i == bs.curr, shortkey);
+ draw_button(window, y, startx + x, bs.sizebutton, bs.label[i],
+ i == bs.curr, shortcut);
}
}
void
get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
- char *extralabel, char *nocancellabel, char *helplabel)
+ char *nocancellabel)
{
int i;
-#define SIZEBUTTON 8
-#define DEFAULT_BUTTON_LABEL LABEL_ok_label
+#define SIZEBUTTON 8
+#define DEFAULT_BUTTON_LABEL BUTTON_OK_LABEL
#define DEFAULT_BUTTON_VALUE BSDDIALOG_OK
-
bs->nbuttons = 0;
bs->curr = 0;
bs->sizebutton = 0;
if (yesoklabel != NULL && conf->button.without_ok == false) {
- bs->label[0] = yesoklabel;
+ bs->label[0] = conf->button.ok_label != NULL ?
+ conf->button.ok_label : yesoklabel;
bs->value[0] = BSDDIALOG_OK;
bs->nbuttons += 1;
}
- if (extralabel != NULL && conf->button.with_extra) {
- bs->label[bs->nbuttons] = extralabel;
+ if (conf->button.with_extra) {
+ bs->label[bs->nbuttons] = conf->button.extra_label != NULL ?
+ conf->button.extra_label : "Extra";
bs->value[bs->nbuttons] = BSDDIALOG_EXTRA;
bs->nbuttons += 1;
}
if (nocancellabel != NULL && conf->button.without_cancel == false) {
- bs->label[bs->nbuttons] = nocancellabel;
+ bs->label[bs->nbuttons] = conf->button.cancel_label ?
+ conf->button.cancel_label : nocancellabel;
bs->value[bs->nbuttons] = BSDDIALOG_CANCEL;
if (conf->button.default_cancel)
bs->curr = bs->nbuttons;
bs->nbuttons += 1;
}
- if (helplabel != NULL && conf->button.with_help) {
- bs->label[bs->nbuttons] = helplabel;
+ if (conf->button.with_help) {
+ bs->label[bs->nbuttons] = conf->button.help_label != NULL ?
+ conf->button.help_label : "Help";
bs->value[bs->nbuttons] = BSDDIALOG_HELP;
bs->nbuttons += 1;
}
@@ -219,44 +220,61 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
}
if (conf->button.default_label != NULL) {
- for (i=0; i<(int)bs->nbuttons; i++) {
- if (strcmp(conf->button.default_label, bs->label[i]) == 0)
+ 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++)
+ for (i = 1; i < (int)bs->nbuttons; i++)
bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i]));
bs->sizebutton += 2;
}
-/* Text */
-static bool is_ncurses_attr(char *text)
+bool shortcut_buttons(int key, struct buttons *bs)
{
+ bool match;
+ unsigned int i;
+
+ match = false;
+ for (i = 0; i < bs->nbuttons; i++) {
+ if (tolower(key) == tolower(bs->label[i][0])) {
+ bs->curr = i;
+ match = true;
+ break;
+ }
+ }
+ return (match);
+}
+
+/* Text */
+static bool is_text_attr(const char *text)
+{
if (strnlen(text, 3) < 3)
- return false;
+ return (false);
if (text[0] != '\\' || text[1] != 'Z')
- return false;
+ return (false);
return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true);
}
-static bool check_set_ncurses_attr(WINDOW *win, char *text)
+static bool check_set_text_attr(WINDOW *win, char *text)
{
-
- if (is_ncurses_attr(text) == false)
- return false;
+ if (is_text_attr(text) == false)
+ return (false);
if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) {
- wattron(win, bsddialog_color( text[2] - '0', COLOR_WHITE, 0));
- return true;
+ wattron(win, bsddialog_color(text[2] - '0', COLOR_WHITE, 0));
+ return (true);
}
switch (text[2]) {
case 'n':
+ wattron(win, t.dialog.color);
wattrset(win, A_NORMAL);
break;
case 'b':
@@ -279,22 +297,20 @@ static bool check_set_ncurses_attr(WINDOW *win, char *text)
break;
}
- return true;
+ return (true);
}
static void
-print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool color)
+print_string(WINDOW *win, int *rows, int cols, int *y, int *x, 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))
+ if (is_text_attr(str+i))
reallen -= 3;
i++;
}
@@ -312,7 +328,7 @@ print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool colo
}
j = *x;
while (j < cols && i < len) {
- if (color && check_set_ncurses_attr(win, str+i)) {
+ if (color && check_set_text_attr(win, str+i)) {
i += 3;
} else {
mvwaddch(win, *y, j, str[i]);
@@ -325,77 +341,28 @@ print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool colo
}
}
-int
-get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword,
- int *maxline, int *nlines)
-{
- int i, buflen, wordlen, linelen;
-
-
- buflen = strlen(text) + 1;
- *maxword = 0;
- wordlen = 0;
- for (i=0; i < buflen; i++) {
- if (text[i] == '\t' || text[i] == '\n' || text[i] == ' ' || text[i] == '\0')
- if (wordlen != 0) {
- *maxword = MAX(*maxword, wordlen);
- wordlen = 0;
- continue;
- }
- if (conf->text.colors && is_ncurses_attr(text + i))
- i += 3;
- else
- wordlen++;
- }
-
- *maxline = linelen = 0;
- *nlines = 1;
- for (i=0; i < buflen; i++) {
- switch (text[i]) {
- case '\n':
- *nlines = *nlines + 1;
- case '\0':
- *maxline = MAX(*maxline, linelen);
- linelen = 0;
- break;
- default:
- if (conf->text.colors && is_ncurses_attr(text + i))
- i += 3;
- else
- linelen++;
- }
- }
- if (*nlines == 1 && *maxline == 0)
- *nlines = 0;
-
- //free(buf);
-
- return 0;
-}
-
-int
-print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
- char *text)
+static int
+print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
{
- char *string;
- int i, j, x, y;
bool loop;
+ int i, j, z, rows, cols, x, y, tablen;
+ char *string;
if ((string = malloc(strlen(text) + 1)) == NULL)
RETURN_ERROR("Cannot build (analyze) text");
+ getmaxyx(pad, rows, cols);
+ tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
+
i = j = x = y = 0;
loop = true;
while (loop) {
string[j] = text[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);
- }
+ if (strchr("\n\t ", string[j]) != NULL || string[j] == '\0') {
+ string[j] = '\0';
+ print_string(pad, &rows, cols, &y, &x, string,
+ conf->text.highlight);
}
switch (text[i]) {
@@ -403,17 +370,17 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
loop = false;
break;
case '\n':
- j = -1;
x = 0;
y++;
+ j = -1;
break;
case '\t':
- for (j=0; j<4 /*tablen*/; j++) {
- x++;
+ for (z = 0; z < tablen; z++) {
if (x >= cols) {
x = 0;
y++;
}
+ x++;
}
j = -1;
break;
@@ -426,9 +393,9 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
j = -1;
}
- if (y >= *rows) { /* check for whitespaces */
- *rows = y + 1;
- wresize(pad, *rows, cols);
+ if (y >= rows) {
+ rows = y + 1;
+ wresize(pad, rows, cols);
}
j++;
@@ -437,44 +404,279 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
free(string);
- return 0;
+ return (0);
}
-/* autosize */
+/* Autosize */
+static int
+text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows,
+ int mincols, bool increasecols, int *h, int *w)
+{
+ int i, j, z, x, y;
+ int tablen, wordlen, maxwordlen, nword, maxwords, line, maxwidth;
+ int *words;
+#define NL -1
+#define WS -2
+
+ maxwords = 1024;
+ if ((words = calloc(maxwords, sizeof(int))) == NULL)
+ RETURN_ERROR("Cannot alloc memory for text autosize");
+
+ tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
+ maxwidth = widget_max_width(conf) - HBORDERS - TEXTHMARGINS;
+
+ nword = 0;
+ wordlen = 0;
+ maxwordlen = 0;
+ i=0;
+ while (true) {
+ if (conf->text.highlight && is_text_attr(text + i)) {
+ i += 3;
+ continue;
+ }
+
+ if (nword + tablen >= maxwords) {
+ maxwords += 1024;
+ if (realloc(words, maxwords * sizeof(int)) == NULL)
+ RETURN_ERROR("Cannot realloc memory for text "
+ "autosize");
+ }
+
+ if (text[i] == '\0') {
+ words[nword] = wordlen;
+ maxwordlen = MAX(wordlen, maxwordlen);
+ break;
+ }
+
+ if (strchr("\t\n ", text[i]) != NULL) {
+ maxwordlen = MAX(wordlen, maxwordlen);
+
+ if (wordlen != 0) {
+ words[nword] = wordlen;
+ nword++;
+ wordlen = 0;
+ }
+
+ if (text[i] == '\t') {
+ for (j = 0; j < tablen; j++)
+ words[nword + j] = 1;
+ nword += tablen;
+ } else {
+ words[nword] = text[i] == '\n' ? NL : WS;
+ nword++;
+ }
+ }
+ else
+ wordlen++;
+
+ i++;
+ }
+
+ if (increasecols) {
+ mincols = MAX(mincols, maxwordlen);
+ mincols = MAX(mincols,
+ (int)conf->auto_minwidth - HBORDERS - TEXTHMARGINS);
+ mincols = MIN(mincols, maxwidth);
+ }
+
+ while (true) {
+ x = 0;
+ y = 1;
+ line=0;
+ for (i = 0; i <= nword; i++) {
+ if (words[i] == NL) {
+ y++;
+ x = 0;
+ }
+ else if (words[i] == WS) {
+ x++;
+ if (x >= mincols) {
+ x = 0;
+ y++;
+ }
+ }
+ else {
+ if (words[i] + x <= mincols)
+ x += words[i];
+ else {
+ for (z = words[i]; z > 0; ) {
+ y++;
+ x = MIN(mincols, z);
+ z -= x;
+ }
+ }
+ }
+ line = MAX(line, x);
+ }
+
+ if (increasecols == false)
+ break;
+ if (y <= maxrows || mincols >= maxwidth)
+ break;
+ mincols++;
+ }
+
+ *h = (nword == 0 && words[0] == 0) ? 0 : y;
+ *w = MIN(mincols, line); /* wtext can be less than mincols */
+
+ free(words);
+
+ return (0);
+}
+
+int
+text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
+ struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext)
+{
+ int wbuttons, maxhtext;
+ bool changewtext;
+
+ wbuttons = 0;
+ if (bs != NULL) {
+ wbuttons = bs->nbuttons * bs->sizebutton;
+ if (bs->nbuttons > 0)
+ wbuttons += (bs->nbuttons-1) * t.button.space;
+ }
+
+ if (cols == BSDDIALOG_AUTOSIZE) {
+ startwtext = MAX(startwtext, wbuttons - TEXTHMARGINS);
+ changewtext = true;
+ } else if (cols == BSDDIALOG_FULLSCREEN) {
+ startwtext = widget_max_width(conf) - VBORDERS - TEXTHMARGINS;
+ changewtext = false;
+ } else { /* fixed */
+ startwtext = cols - VBORDERS - TEXTHMARGINS;
+ changewtext = false;
+ }
+
+ if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
+ maxhtext = widget_max_height(conf) - VBORDERS - rowsnotext;
+ if (bs != NULL)
+ maxhtext -= 2;
+ } else { /* fixed */
+ maxhtext = rows - VBORDERS - rowsnotext;
+ if (bs != NULL)
+ maxhtext -= 2;
+ }
+
+ if (startwtext <= 0 && changewtext)
+ startwtext = 1;
+ if (maxhtext <= 0 || startwtext <= 0) {
+ *htext = *wtext = 0;
+ return (0);
+ }
+
+ if (text_autosize(conf, text, maxhtext, startwtext, changewtext,
+ htext, wtext) != 0)
+ return (BSDDIALOG_ERROR);
+
+ return (0);
+}
-/*
- * 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.shadow.h : LINES - 1) <= 0)
- RETURN_ERROR("Terminal too small, LINES - shadow <= 0");
+ maxheight = conf->shadow ? SCREENLINES - t.shadow.h : SCREENLINES;
+ if (maxheight <= 0)
+ RETURN_ERROR("Terminal too small, screen lines - shadow <= 0");
- if (conf->y > 0)
- if ((maxheight -= conf->y) <=0)
- RETURN_ERROR("Terminal too small, LINES - shadow - y <= 0");
+ if (conf->y > 0) {
+ maxheight -= conf->y;
+ if (maxheight <= 0)
+ RETURN_ERROR("Terminal too small, screen lines - "
+ "shadow - y <= 0");
+ }
- return maxheight;
+ 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.shadow.w : 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");
+ maxwidth = conf->shadow ? SCREENCOLS - t.shadow.w : SCREENCOLS;
+ if (maxwidth <= 0)
+ RETURN_ERROR("Terminal too small, screen cols - shadow <= 0");
+
+ if (conf->x > 0) {
+ maxwidth -= conf->x;
+ if (maxwidth <= 0)
+ RETURN_ERROR("Terminal too small, screen cols - shadow "
+ "- x <= 0");
+ }
+
+ return (maxwidth);
+}
+
+int
+widget_min_height(struct bsddialog_conf *conf, int htext, int minwidget,
+ bool withbuttons)
+{
+ int min;
+
+ min = 0;
+
+ /* buttons */
+ if (withbuttons)
+ min += 2; /* buttons and border */
+
+ /* text */
+ min += htext;
+
+ /* specific widget min height */
+ min += minwidget;
+
+ /* dialog borders */
+ min += HBORDERS;
+ /* conf.auto_minheight */
+ min = MAX(min, (int)conf->auto_minheight);
+ /* avoid terminal overflow */
+ min = MIN(min, widget_max_height(conf));
+
+ return (min);
+}
+
+int
+widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
+ struct buttons *bs)
+
+{
+ int min, delimtitle;
+
+ min = 0;
+
+ /* buttons */
+ if (bs != NULL) {
+ min += bs->nbuttons * bs->sizebutton;
+ min += bs->nbuttons > 0 ? (bs->nbuttons-1) * t.button.space : 0;
+ }
+
+ /* text */
+ if (wtext > 0)
+ min = MAX(min, wtext + TEXTHMARGINS);
+
+ /* specific widget min width */
+ min = MAX(min, minwidget);
+
+ /* title */
+ if (conf->title != NULL) {
+ delimtitle = t.dialog.delimtitle ? 2 : 0;
+ min = MAX(min, (int)strlen(conf->title) + 2 + delimtitle);
+ }
+
+ /* bottom title */
+ if (conf->bottomtitle != NULL)
+ min = MAX(min, (int)strlen(conf->bottomtitle) + 4);
+
+ /* dialog borders */
+ min += VBORDERS;
+ /* conf.auto_minwidth */
+ min = MAX(min, (int)conf->auto_minwidth);
+ /* avoid terminal overflow */
+ min = MIN(min, widget_max_width(conf));
- return maxwidth;
+ return (min);
}
int
@@ -483,7 +685,7 @@ 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;
+ return (BSDDIALOG_ERROR);
if (rows == BSDDIALOG_FULLSCREEN)
*h = maxheight;
@@ -491,13 +693,13 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
RETURN_ERROR("Negative (less than -1) height");
else if (rows > BSDDIALOG_AUTOSIZE) {
if ((*h = rows) > maxheight)
- RETURN_ERROR("Height too big (> terminal height - "\
- "shadow");
+ 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;
+ return (BSDDIALOG_ERROR);
if (cols == BSDDIALOG_FULLSCREEN)
*w = maxwidth;
@@ -505,45 +707,45 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
RETURN_ERROR("Negative (less than -1) width");
else if (cols > BSDDIALOG_AUTOSIZE) {
if ((*w = cols) > maxwidth)
- RETURN_ERROR("Width too big (> terminal width - shadow)");
+ RETURN_ERROR("Width too big (> terminal width - "
+ "shadow)");
}
/* cols == AUTOSIZE: each widget has to set its size */
- return 0;
+ 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;
+ *y = SCREENLINES/2 - (h + t.shadow.h)/2;
else if (conf->y < BSDDIALOG_CENTER)
RETURN_ERROR("Negative begin y (less than -1)");
- else if (conf->y >= LINES)
+ else if (conf->y >= SCREENLINES)
RETURN_ERROR("Begin Y under the terminal");
else
*y = conf->y;
- if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > LINES)
- RETURN_ERROR("The lower of the box under the terminal "\
+ if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > SCREENLINES)
+ 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;
+ *x = SCREENCOLS/2 - (w + t.shadow.w)/2;
else if (conf->x < BSDDIALOG_CENTER)
RETURN_ERROR("Negative begin x (less than -1)");
- else if (conf->x >= COLS)
+ else if (conf->x >= SCREENCOLS)
RETURN_ERROR("Begin X over the right of the terminal");
else
*x = conf->x;
- if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > COLS)
- RETURN_ERROR("The right of the box over the terminal "\
+ if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > SCREENCOLS)
+ RETURN_ERROR("The right of the box over the terminal "
"(begin X + width (+ shadow) > terminal cols)");
- return 0;
+ return (0);
}
/* Widgets builders */
@@ -552,39 +754,40 @@ 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.dialog.lineraisecolor : t.dialog.linelowercolor;
- rightcolor = elev == RAISED ?
- t.dialog.linelowercolor : t.dialog.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);
+ int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee;
+
+ if (conf->no_lines)
+ return;
+
+ if (conf->ascii_lines) {
+ ls = rs = '|';
+ ts = bs = '-';
+ tl = tr = bl = br = ltee = rtee = '+';
+ } else {
+ 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;
}
+
+ leftcolor = elev == RAISED ?
+ t.dialog.lineraisecolor : t.dialog.linelowercolor;
+ rightcolor = elev == RAISED ?
+ t.dialog.linelowercolor : t.dialog.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 *
@@ -595,119 +798,113 @@ new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols,
if ((win = newwin(rows, cols, y, x)) == NULL) {
set_error_string("Cannot build boxed window");
- return NULL;
+ return (NULL);
}
wbkgd(win, t.dialog.color);
draw_borders(conf, win, rows, cols, elev);
- return win;
+ 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)
+draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ WINDOW *textpad, const char *text, struct buttons *bs, bool shortcutbuttons)
{
- int ts, ltee, rtee;
- int colordelimtitle;
+ int h, w, ts, ltee, rtee;
ts = conf->ascii_lines ? '-' : ACS_HLINE;
ltee = conf->ascii_lines ? '+' : ACS_LTEE;
rtee = conf->ascii_lines ? '+' : ACS_RTEE;
- colordelimtitle = elev == RAISED ?
- t.dialog.lineraisecolor : t.dialog.linelowercolor;
+
+ getmaxyx(widget, h, w);
if (shadow != NULL)
wnoutrefresh(shadow);
- // move / resize now or the caller?
- draw_borders(conf, widget, h, w, elev);
+ draw_borders(conf, widget, h, w, RAISED);
if (conf->title != NULL) {
if (t.dialog.delimtitle && conf->no_lines == false) {
- wattron(widget, colordelimtitle);
- mvwaddch(widget, 0, w/2 - strlen(conf->title)/2 - 1, rtee);
- wattroff(widget, colordelimtitle);
+ wattron(widget, t.dialog.lineraisecolor);
+ mvwaddch(widget, 0, w/2-strlen(conf->title)/2-1, rtee);
+ wattroff(widget, t.dialog.lineraisecolor);
}
wattron(widget, t.dialog.titlecolor);
mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title);
wattroff(widget, t.dialog.titlecolor);
if (t.dialog.delimtitle && conf->no_lines == false) {
- wattron(widget, colordelimtitle);
+ wattron(widget, t.dialog.lineraisecolor);
waddch(widget, ltee);
- wattroff(widget, colordelimtitle);
+ wattroff(widget, t.dialog.lineraisecolor);
}
}
+ if (bs != NULL) {
+ if (conf->no_lines == false) {
+ wattron(widget, t.dialog.lineraisecolor);
+ mvwaddch(widget, h-3, 0, ltee);
+ mvwhline(widget, h-3, 1, ts, w-2);
+ wattroff(widget, t.dialog.lineraisecolor);
+
+ wattron(widget, t.dialog.linelowercolor);
+ mvwaddch(widget, h-3, w-1, rtee);
+ wattroff(widget, t.dialog.linelowercolor);
+ }
+ draw_buttons(widget, *bs, shortcutbuttons);
+ }
+
if (conf->bottomtitle != NULL) {
wattron(widget, t.dialog.bottomtitlecolor);
wmove(widget, h - 1, w/2 - strlen(conf->bottomtitle)/2 - 1);
- waddch(widget, '[');
+ waddch(widget, ' ');
waddstr(widget, conf->bottomtitle);
- waddch(widget, ']');
+ waddch(widget, ' ');
wattroff(widget, t.dialog.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.dialog.lineraisecolor);
- mvwaddch(widget, h-3, 0, ltee);
- mvwhline(widget, h-3, 1, ts, w-2);
- wattroff(widget, t.dialog.lineraisecolor);
-
- wattron(widget, t.dialog.linelowercolor);
- mvwaddch(widget, h-3, w-1, rtee);
- wattroff(widget, t.dialog.linelowercolor);
- }
-
wnoutrefresh(widget);
- if (textpad == NULL)
- return 0; /* widget_init() ends */
+ if (textpad != NULL && text != NULL) /* textbox */
+ if (print_textpad(conf, textpad, text) !=0)
+ return (BSDDIALOG_ERROR);
- if (text != NULL) /* programbox etc */
- if (print_textpad(conf, textpad, htextpad,
- w - HBORDERS - t.text.hmargin * 2, text) !=0)
- return BSDDIALOG_ERROR;
-
- return 0;
+ 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)
+update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ int y, int x, int h, int w, WINDOW *textpad, const char *text,
+ struct buttons *bs, bool shortcutbuttons)
{
int error;
- /* nothing for now */
+ if (shadow != NULL) {
+ wclear(shadow);
+ mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
+ wresize(shadow, h, w);
+ }
+
+ wclear(widget);
+ mvwin(widget, y, x);
+ wresize(widget, h, w);
+
+ if (textpad != NULL) {
+ wclear(textpad);
+ wresize(textpad, 1, w - HBORDERS - TEXTHMARGINS);
+ }
- error = draw_widget_withtextpad(conf, shadow, widget, h, w,
- elev, textpad, htextpad, text, buttons);
+ error = draw_dialog(conf, shadow, widget, textpad, text, bs,
+ shortcutbuttons);
- return error;
+ 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)
+new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y,
+ int x, int h, int w, WINDOW **textpad, const char *text, struct buttons *bs,
+ bool shortcutbuttons)
{
int error;
@@ -718,23 +915,16 @@ new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
wbkgd(*shadow, t.shadow.color);
}
- if ((*widget = new_boxed_window(conf, y, x, h, w, elev)) == NULL) {
+ if ((*widget = new_boxed_window(conf, y, x, h, w, RAISED)) == NULL) {
if (conf->shadow)
delwin(*shadow);
- return BSDDIALOG_ERROR;
+ 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.text.hmargin * 2);
+ if (textpad != NULL && text != NULL) { /* textbox */
+ *textpad = newpad(1, w - HBORDERS - TEXTHMARGINS);
if (*textpad == NULL) {
- delwin(*textpad);
+ delwin(*widget);
if (conf->shadow)
delwin(*shadow);
RETURN_ERROR("Cannot build the pad window for text");
@@ -742,19 +932,20 @@ new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
wbkgd(*textpad, t.dialog.color);
}
- error = draw_widget_withtextpad(conf, *shadow, *widget, h, w, elev,
- *textpad, htextpad, text, buttons);
+ error = draw_dialog(conf, *shadow, *widget,
+ textpad == NULL ? NULL : *textpad, text, bs, shortcutbuttons);
- return error;
+ return (error);
}
void
-end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w,
- WINDOW *textpad, WINDOW *shadow)
+end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ WINDOW *textpad)
{
- int y, x;
+ int y, x, h, w;
- getbegyx(window, y, x); /* for clear, add y & x to args? */
+ getbegyx(widget, y, x);
+ getmaxyx(widget, h, w);
if (conf->sleep > 0)
sleep(conf->sleep);
@@ -762,7 +953,7 @@ end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w
if (textpad != NULL)
delwin(textpad);
- delwin(window);
+ delwin(widget);
if (conf->shadow)
delwin(shadow);
@@ -774,4 +965,4 @@ end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w
*conf->get_height = h;
if (conf->get_width != NULL)
*conf->get_width = w;
-}
+} \ No newline at end of file