aboutsummaryrefslogtreecommitdiff
path: root/lib/menubox.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/menubox.c')
-rw-r--r--lib/menubox.c194
1 files changed, 151 insertions, 43 deletions
diff --git a/lib/menubox.c b/lib/menubox.c
index 72038d4b0246..147fa66c8c27 100644
--- a/lib/menubox.c
+++ b/lib/menubox.c
@@ -31,9 +31,9 @@
#include <string.h>
#ifdef PORTNCURSES
-#include <ncurses/curses.h>
+#include <ncurses/ncurses.h>
#else
-#include <curses.h>
+#include <ncurses.h>
#endif
#include "bsddialog.h"
@@ -271,6 +271,61 @@ getfastprev(int menurows, struct bsddialog_menugroup *groups, int *abs,
} while (*abs != a && *abs > start - menurows && i > 0);
}
+static bool
+getnextshortcut(struct bsddialog_conf *conf, enum menumode mode, int ngroups,
+ struct bsddialog_menugroup *groups, int *abs, int *group, int *rel,
+ int key)
+{
+ int i, j, a, ch, ng, nr, na;
+ bool mainloop;
+
+ if (*abs < 0 || ngroups < 0 || *rel < 0 || mode == BUILDLISTMODE)
+ return false;
+
+ na = a = -1;
+ mainloop = true;
+ for (i = 0; i < ngroups && mainloop; i++) {
+ if (groups[i].type == BSDDIALOG_SEPARATOR) {
+ a += groups[i].nitems;
+ continue;
+ }
+ for (j = 0; j < (int)groups[i].nitems; j++) {
+ a++;
+ if (a == *abs)
+ continue;
+
+ if (conf->menu.no_name)
+ ch = groups[i].items[j].desc[0];
+ else
+ ch = groups[i].items[j].name[0];
+
+ if (ch == key) {
+ if (a < *abs && na == -1) {
+ na = a;
+ ng = i;
+ nr = j;
+ }
+ if (a > *abs) {
+ na = a;
+ ng = i;
+ nr = j;
+ mainloop = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (na != -1) {
+ *abs = na;
+ *group = ng;
+ *rel = nr;
+ return (true);
+ }
+
+ return (false);
+}
+
static enum menumode
getmode(enum menumode mode, struct bsddialog_menugroup group)
{
@@ -292,10 +347,8 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
struct bsddialog_menuitem item, enum menumode mode, struct lineposition pos,
bool curr)
{
- int color, colorname, linech;
-
- color = curr ? t.menu.f_desccolor : t.menu.desccolor;
- colorname = curr ? t.menu.f_namecolor : t.menu.namecolor;
+ int colordesc, colorname, colorshortcut, linech;
+ char *shortcut;
if (mode == SEPARATORMODE) {
if (conf->no_lines == false) {
@@ -322,14 +375,15 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
/* selector */
wmove(pad, y, pos.xselector);
- wattron(pad, color);
+ wattron(pad, t.menu.selectorcolor);
if (mode == CHECKLISTMODE)
wprintw(pad, "[%c]", item.on ? 'X' : ' ');
if (mode == RADIOLISTMODE)
wprintw(pad, "(%c)", item.on ? '*' : ' ');
- wattroff(pad, color);
+ wattroff(pad, t.menu.selectorcolor);
/* name */
+ colorname = curr ? t.menu.f_namecolor : t.menu.namecolor;
if (mode != BUILDLISTMODE && conf->menu.no_name == false) {
wattron(pad, colorname);
mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.name);
@@ -337,23 +391,47 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
}
/* description */
- if (conf->menu.no_desc == false) {
- if ((mode == BUILDLISTMODE || conf->menu.no_name) && curr == false)
- color = item.on ? t.menu.namecolor : t.menu.desccolor;
- wattron(pad, color);
+ if (mode == BUILDLISTMODE) {
+ if (curr == false)
+ colordesc = item.on ? t.menu.namecolor : t.menu.desccolor;
+ else
+ colordesc = t.menu.f_namecolor;
+ }
+ else {
+ if (conf->menu.no_name)
+ colordesc = curr ? t.menu.f_namecolor : t.menu.namecolor;
+ else
+ colordesc = curr ? t.menu.f_desccolor : t.menu.desccolor;
+ }
+ if (mode == BUILDLISTMODE || conf->menu.no_desc == false) {
+ wattron(pad, colordesc);
if (conf->menu.no_name)
mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.desc);
else
mvwaddstr(pad, y, pos.xdesc, item.desc);
- wattroff(pad, color);
+ wattroff(pad, colordesc);
}
- /* bottom desc (item help) */
- if (item.bottomdesc != NULL && item.bottomdesc[0] != '\0') {
- move(LINES-1, 2);
- clrtoeol();
- addstr(item.bottomdesc);
+ /* shortcut */
+ if (mode != BUILDLISTMODE && conf->menu.shortcut_buttons == false) {
+ colorshortcut = curr ? t.menu.f_shortcutcolor : t.menu.shortcutcolor;
+ wattron(pad, colorshortcut);
+
+ if (conf->menu.no_name)
+ shortcut = item.desc;
+ else
+ shortcut = item.name;
+ wmove(pad, y, pos.xname + item.depth * DEPTHSPACE);
+ if (shortcut != NULL && shortcut[0] != '\0')
+ waddch(pad, shortcut[0]);
+ wattroff(pad, colorshortcut);
+}
+ /* bottom description */
+ move(LINES-1, 2);
+ clrtoeol();
+ if (item.bottomdesc != NULL) {
+ addstr(item.bottomdesc);
refresh();
}
}
@@ -374,6 +452,8 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
*w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
/* line size */
*w = MAX(*w, linelen + 6);
+ /* conf.auto_minwidth */
+ *w = MAX(*w, (int)conf->auto_minwidth);
/*
* avoid terminal overflow,
* -1 fix false negative with big menu over the terminal and
@@ -395,8 +475,13 @@ menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
else /* h autosize with a fixed menurows */
*h = *h + *menurows + 2;
+ /* conf.auto_minheight */
+ *h = MAX(*h, (int)conf->auto_minheight);
/* avoid terminal overflow */
*h = MIN(*h, widget_max_height(conf));
+ /* avoid menurows overflow */
+ /* manual: with rows=autosize menurows!=0 is maxmenurows */
+ *menurows = MIN(*h - 6 - textrow, (int)*menurows);
}
else {
if (*menurows == 0)
@@ -440,9 +525,9 @@ update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
int totnitems, unsigned int menurows, int ymenupad)
{
- if (totnitems > (int) menurows) {
- draw_borders(conf, menuwin, h, w, LOWERED);
+ draw_borders(conf, menuwin, h, w, LOWERED);
+ if (totnitems > (int) menurows) {
wattron(menuwin, t.menu.arrowcolor);
if (ymenupad > 0)
@@ -466,12 +551,14 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
WINDOW *shadow, *widget, *textpad, *menuwin, *menupad;
int i, j, y, x, h, w, htextpad, output, input;
int ymenupad, ys, ye, xs, xe, abs, g, rel, totnitems;
- bool loop, automenurows;
+ bool loop, automenurows, shortcut_buttons;
struct buttons bs;
struct bsddialog_menuitem *item;
enum menumode currmode;
struct lineposition pos = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
+
+ shortcut_buttons = conf->menu.shortcut_buttons;
+
automenurows = menurows == BSDDIALOG_AUTOSIZE ? true : false;
totnitems = 0;
@@ -497,7 +584,7 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
}
pos.maxprefix = MAX(pos.maxprefix, strlen(item->prefix));
- pos.maxdepth = MAX((int) pos.maxdepth, item->depth);
+ pos.maxdepth = MAX(pos.maxdepth, item->depth);
pos.maxname = MAX(pos.maxname, strlen(item->name));
pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc));
}
@@ -536,19 +623,22 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
menurows+2, w-4, LOWERED);
menupad = newpad(totnitems, pos.line);
- wbkgd(menupad, t.widget.color);
+ wbkgd(menupad, t.dialog.color);
- getfirst_with_default(conf, ngroups, groups, &abs, &g, &rel);
ymenupad = 0;
for (i=0; i<ngroups; i++) {
currmode = getmode(mode, groups[i]);
for (j=0; j < (int) groups[i].nitems; j++) {
item = &groups[i].items[j];
- drawitem(conf, menupad, ymenupad, *item, currmode,
- pos, ymenupad == abs);
+ drawitem(conf, menupad, ymenupad, *item, currmode, pos,
+ false);
ymenupad++;
}
}
+ getfirst_with_default(conf, ngroups, groups, &abs, &g, &rel);
+ currmode = getmode(mode, groups[g]);
+ item = &groups[g].items[rel];
+ drawitem(conf, menupad, abs, *item, currmode, pos, true);
ys = y + h - 5 - menurows + 1;
ye = y + h - 5 ;
@@ -568,11 +658,9 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
wrefresh(menuwin);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, h-2, w, bs, shortcut_buttons);
wrefresh(widget);
- item = &groups[g].items[rel];
- currmode = getmode(mode, groups[g]);
loop = true;
while(loop) {
input = getch();
@@ -590,26 +678,26 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, h-2, w, bs, shortcut_buttons);
wrefresh(widget);
break;
case KEY_LEFT:
if (bs.curr > 0) {
bs.curr--;
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, h-2, w, bs, shortcut_buttons);
wrefresh(widget);
}
break;
case KEY_RIGHT:
if (bs.curr < (int) bs.nbuttons - 1) {
bs.curr++;
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, h-2, w, bs, shortcut_buttons);
wrefresh(widget);
}
break;
case KEY_CTRL('E'): /* add conf->menu.extrahelpkey ? */
case KEY_F(1):
- if (conf->hfile == NULL)
+ if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
return BSDDIALOG_ERROR;
@@ -649,7 +737,7 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
RAISED, textpad, &htextpad, text, true) != 0)
return BSDDIALOG_ERROR;
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, h-2, w, bs, shortcut_buttons);
wrefresh(widget);
prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
@@ -680,12 +768,6 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
refresh();
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 (abs < 0)
@@ -752,6 +834,32 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
}
drawitem(conf, menupad, abs, *item, currmode, pos, true);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ default:
+ if (shortcut_buttons) {
+ for (i = 0; i < (int) bs.nbuttons; i++)
+ if (tolower(input) == tolower((bs.label[i])[0])) {
+ output = bs.value[i];
+ if (currmode == MENUMODE)
+ item->on = true;
+ loop = false;
+ }
+ break;
+ }
+
+ drawitem(conf, menupad, abs, *item, currmode, pos, false);
+ getnextshortcut(conf, currmode, ngroups, groups, &abs,
+ &g, &rel, input);
+ item = &groups[g].items[rel];
+ currmode = getmode(mode, groups[g]);
+ drawitem(conf, menupad, abs, *item, currmode, pos, true);
+ if (ymenupad > abs && ymenupad > 0)
+ ymenupad = abs;
+ if ((int)(ymenupad + menurows) <= abs)
+ ymenupad = abs - menurows + 1;
+ update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
+ menurows, ymenupad);
+ wrefresh(menuwin);
+ prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
}
}
@@ -926,8 +1034,8 @@ bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
padscols = (w-5)/2 - 2;
leftpad = newpad(nitems, pos.line);
rightpad = newpad(nitems, pos.line);
- wbkgd(leftpad, t.widget.color);
- wbkgd(rightpad, t.widget.color);
+ wbkgd(leftpad, t.dialog.color);
+ wbkgd(rightpad, t.dialog.color);
currH = 0;
currV = startleft ? LEFT : RIGHT;