diff options
Diffstat (limited to 'lib/lib_util.c')
-rw-r--r-- | lib/lib_util.c | 755 |
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 |