aboutsummaryrefslogtreecommitdiff
path: root/lib/menubox.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/menubox.c')
-rw-r--r--lib/menubox.c1079
1 files changed, 365 insertions, 714 deletions
diff --git a/lib/menubox.c b/lib/menubox.c
index c9fb182422ea..0d8e3b14521c 100644
--- a/lib/menubox.c
+++ b/lib/menubox.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
@@ -28,19 +28,13 @@
#include <sys/param.h>
#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
+#include <stdlib.h>
#include <string.h>
-
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-/* "Menu": checklist - menu - mixedlist - radiolist - buildlist */
+#include "lib_util.h"
#define DEPTHSPACE 4
#define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */
@@ -48,7 +42,6 @@
extern struct bsddialog_theme t;
enum menumode {
- BUILDLISTMODE,
CHECKLISTMODE,
MENUMODE,
MIXEDLISTMODE,
@@ -69,267 +62,152 @@ struct lineposition {
unsigned int line;
};
-static int checkradiolist(int nitems, struct bsddialog_menuitem *items)
-{
- int i, error;
-
- error = 0;
- for (i=0; i<nitems; i++) {
- if (error > 0)
- items[i].on = false;
-
- if (items[i].on == true)
- error++;
- }
-
- return (error == 0 ? 0 : -1);
-}
-
-static int checkmenu(int nitems, struct bsddialog_menuitem *items) // useful?
-{
- int i, error;
-
- error = 0;
- for (i=0; i<nitems; i++) {
- if (items[i].on == true)
- error++;
-
- items[i].on = false;
- }
-
- return (error == 0 ? 0 : -1);
-}
+struct privateitem {
+ bool on;
+ int group;
+ int index;
+ enum menumode type;
+ struct bsddialog_menuitem *item;
+};
static void
-getfirst(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group,
- int *rel)
+set_on_output(struct bsddialog_conf *conf, int output, int ngroups,
+ struct bsddialog_menugroup *groups, struct privateitem *pritems)
{
- int i, a;
+ int i, j, abs;
+
+ if (output != BSDDIALOG_OK && !conf->menu.on_without_ok)
+ return;
- *abs = *rel = *group = -1;
- a = 0;
- for (i=0; i<ngroups; i++) {
+ for(i = abs = 0; i < ngroups; i++) {
if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ abs += groups[i].nitems;
continue;
}
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a;
- *rel = 0;
- break;
+
+ for(j = 0; j < (int)groups[i].nitems; j++) {
+ groups[i].items[j].on = pritems[abs].on;
+ abs++;
}
}
}
-static void
-getfirst_with_default(struct bsddialog_conf *conf, int ngroups,
- struct bsddialog_menugroup *groups, int *abs, int *group, int *rel)
+static int getprev(struct privateitem *pritems, int abs)
{
- int i, j, a;
- struct bsddialog_menuitem *item;
-
- getfirst(ngroups, groups, abs, group, rel);
- if (*abs < 0)
- return;
-
- a = *abs;
+ int i;
- for (i=*group; i<ngroups; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ for (i = abs - 1; i >= 0; i--) {
+ if (pritems[i].type == SEPARATORMODE)
continue;
- }
- for (j = 0; j < (int) groups[i].nitems; j++) {
- item = &groups[i].items[j];
- if (conf->menu.default_item != NULL && item->name != NULL) {
- if (strcmp(item->name, conf->menu.default_item) == 0) {
- *abs = a;
- *group = i;
- *rel = j;
- return;
- }
- }
- a++;
- }
+ return (i);
}
+
+ return (abs);
}
-static void
-getlast(int totnitems, int ngroups, struct bsddialog_menugroup *groups,
- int *abs, int *group, int *rel)
+static int getnext(int npritems, struct privateitem *pritems, int abs)
{
- int i, a;
+ int i;
- a = totnitems - 1;
- for (i = ngroups-1; i>=0; i--) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a -= groups[i].nitems;
+ for (i = abs + 1; i < npritems; i++) {
+ if (pritems[i].type == SEPARATORMODE)
continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a;
- *rel = groups[i].nitems - 1;
- break;
- }
+ return (i);
}
+
+ return (abs);
}
-static void
-getnext(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group,
- int *rel)
+static int
+getfirst_with_default(int npritems, struct privateitem *pritems, int ngroups,
+ struct bsddialog_menugroup *groups, int *focusgroup, int *focusitem)
{
- int i, a;
-
- if (*abs < 0 || *group < 0 || *rel < 0)
- return;
-
- if (*rel + 1 < (int) groups[*group].nitems) {
- *rel = *rel + 1;
- *abs = *abs + 1;
- return;
+ int i, abs;
+
+ if ((abs = getnext(npritems, pritems, -1)) < 0)
+ return (abs);
+
+ if (focusgroup == NULL || focusitem == NULL)
+ return (abs);
+ if (*focusgroup < 0 || *focusgroup >= ngroups)
+ return (abs);
+ if (groups[*focusgroup].type == BSDDIALOG_SEPARATOR)
+ return (abs);
+ if (*focusitem < 0 || *focusitem >= (int)groups[*focusgroup].nitems)
+ return (abs);
+
+ for (i = abs; i < npritems; i++) {
+ if (pritems[i].group == *focusgroup &&
+ pritems[i].index == *focusitem)
+ return (i);
}
- if (*group + 1 > ngroups)
- return;
-
- a = *abs;
- for (i = *group + 1; i < ngroups; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
- continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a + 1;
- *rel = 0;
- break;
- }
- }
+ return (abs);
}
-static void
-getfastnext(int menurows, int ngroups, struct bsddialog_menugroup *groups,
- int *abs, int *group, int *rel)
+static int
+getfastnext(int menurows, int npritems, struct privateitem *pritems, int abs)
{
int a, start, i;
- start = *abs;
+ start = abs;
i = menurows;
do {
- a = *abs;
- getnext(ngroups, groups, abs, group, rel);
+ a = abs;
+ abs = getnext(npritems, pritems, abs);
i--;
- } while (*abs != a && *abs < start + menurows && i > 0);
-}
-
-static void
-getprev(struct bsddialog_menugroup *groups, int *abs, int *group, int *rel)
-{
- int i, a;
-
- if (*abs < 0 || *group < 0 || *rel < 0)
- return;
-
- if (*rel > 0) {
- *rel = *rel - 1;
- *abs = *abs - 1;
- return;
- }
-
- if (*group - 1 < 0)
- return;
+ } while (abs != a && abs < start + menurows && i > 0);
- a = *abs;
- for (i = *group - 1; i >= 0; i--) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a -= (int) groups[i].nitems;
- continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a - 1;
- *rel = (int) groups[i].nitems - 1;
- break;
- }
- }
+ return (abs);
}
-static void
-getfastprev(int menurows, struct bsddialog_menugroup *groups, int *abs,
- int *group, int *rel)
+static int
+getfastprev(int menurows, struct privateitem *pritems, int abs)
{
int a, start, i;
- start = *abs;
+ start = abs;
i = menurows;
do {
- a = *abs;
- getprev(groups, abs, group, rel);
+ a = abs;
+ abs = getprev(pritems, abs);
i--;
- } while (*abs != a && *abs > start - menurows && i > 0);
+ } while (abs != a && abs > start - menurows && i > 0);
+
+ return (abs);
}
-static bool
-getnextshortcut(struct bsddialog_conf *conf, enum menumode mode, int ngroups,
- struct bsddialog_menugroup *groups, int *abs, int *group, int *rel,
- int key)
+static int
+getnextshortcut(struct bsddialog_conf *conf, int npritems,
+ struct privateitem *pritems, int abs, int key)
{
- int i, j, a, ch, ng, nr, na;
- bool mainloop;
-
- if (*abs < 0 || ngroups < 0 || *rel < 0 || mode == BUILDLISTMODE)
- return false;
+ int i, ch, next;
- na = a = -1;
- mainloop = true;
- for (i = 0; i < ngroups && mainloop; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ next = -1;
+ for (i = 0; i < npritems; i++) {
+ if (pritems[i].type == SEPARATORMODE)
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 (conf->menu.no_name)
+ ch = pritems[i].item->desc[0];
+ else
+ ch = pritems[i].item->name[0];
+
+ if (ch == key) {
+ if (i > abs)
+ return (i);
- if (na != -1) {
- *abs = na;
- *group = ng;
- *rel = nr;
- return (true);
+ if (i < abs && next == -1)
+ next = i;
+ }
}
- return (false);
+ return (next != -1 ? next : abs);
}
static enum menumode
getmode(enum menumode mode, struct bsddialog_menugroup group)
{
-
if (mode == MIXEDLISTMODE) {
if (group.type == BSDDIALOG_SEPARATOR)
mode = SEPARATORMODE;
@@ -339,16 +217,25 @@ getmode(enum menumode mode, struct bsddialog_menugroup group)
mode = CHECKLISTMODE;
}
- return mode;
+ return (mode);
}
static void
drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
- struct bsddialog_menuitem item, enum menumode mode, struct lineposition pos,
- bool curr)
+ struct lineposition pos, struct privateitem *pritem, bool focus)
{
int colordesc, colorname, colorshortcut, linech;
- char *shortcut;
+ unsigned int depth;
+ enum menumode mode;
+ const char *prefix, *name, *desc, *bottomdesc, *shortcut;
+
+ prefix = pritem->item->prefix;
+ name = pritem->item->name;
+ depth = pritem->item->depth;
+ desc = pritem->item->desc;
+ bottomdesc = pritem->item->bottomdesc;
+
+ mode = pritem->type;
if (mode == SEPARATORMODE) {
if (conf->no_lines == false) {
@@ -357,140 +244,132 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
mvwhline(pad, y, 0, linech, pos.line);
wattroff(pad, t.menu.desccolor);
}
- wmove(pad, y, pos.line/2 - (strlen(item.name)+strlen(item.desc))/2);
+ wmove(pad, y,
+ pos.line/2 - (strlen(name) + strlen(desc)) / 2 );
wattron(pad, t.menu.namesepcolor);
- waddstr(pad, item.name);
+ waddstr(pad, name);
wattroff(pad, t.menu.namesepcolor);
- if (strlen(item.name) > 0 && strlen(item.desc) > 0)
+ if (strlen(name) > 0 && strlen(desc) > 0)
waddch(pad, ' ');
wattron(pad, t.menu.descsepcolor);
- waddstr(pad, item.desc);
+ waddstr(pad, desc);
wattroff(pad, t.menu.descsepcolor);
return;
}
/* prefix */
- if (item.prefix != NULL && item.prefix[0] != '\0')
- mvwaddstr(pad, y, 0, item.prefix);
+ if (prefix != NULL && prefix[0] != '\0')
+ mvwaddstr(pad, y, 0, prefix);
/* selector */
wmove(pad, y, pos.xselector);
wattron(pad, t.menu.selectorcolor);
if (mode == CHECKLISTMODE)
- wprintw(pad, "[%c]", item.on ? 'X' : ' ');
+ wprintw(pad, "[%c]", pritem->on ? 'X' : ' ');
if (mode == RADIOLISTMODE)
- wprintw(pad, "(%c)", item.on ? '*' : ' ');
+ wprintw(pad, "(%c)", pritem->on ? '*' : ' ');
wattroff(pad, t.menu.selectorcolor);
/* name */
- colorname = curr ? t.menu.f_namecolor : t.menu.namecolor;
- if (mode != BUILDLISTMODE && conf->menu.no_name == false) {
+ colorname = focus ? t.menu.f_namecolor : t.menu.namecolor;
+ if (conf->menu.no_name == false) {
wattron(pad, colorname);
- mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.name);
+ mvwaddstr(pad, y, pos.xname + depth * DEPTHSPACE, name);
wattroff(pad, colorname);
}
/* description */
- 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) {
+ if (conf->menu.no_name)
+ colordesc = focus ? t.menu.f_namecolor : t.menu.namecolor;
+ else
+ colordesc = focus ? t.menu.f_desccolor : t.menu.desccolor;
+
+ if (conf->menu.no_desc == false) {
wattron(pad, colordesc);
if (conf->menu.no_name)
- mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.desc);
+ mvwaddstr(pad, y, pos.xname + depth * DEPTHSPACE, desc);
else
- mvwaddstr(pad, y, pos.xdesc, item.desc);
+ mvwaddstr(pad, y, pos.xdesc, desc);
wattroff(pad, colordesc);
}
/* shortcut */
- if (mode != BUILDLISTMODE && conf->menu.shortcut_buttons == false) {
- colorshortcut = curr ? t.menu.f_shortcutcolor : t.menu.shortcutcolor;
+ if (conf->menu.shortcut_buttons == false) {
+ colorshortcut = focus ?
+ t.menu.f_shortcutcolor : t.menu.shortcutcolor;
wattron(pad, colorshortcut);
if (conf->menu.no_name)
- shortcut = item.desc;
+ shortcut = desc;
else
- shortcut = item.name;
- wmove(pad, y, pos.xname + item.depth * DEPTHSPACE);
+ shortcut = name;
+ wmove(pad, y, pos.xname + depth * DEPTHSPACE);
if (shortcut != NULL && shortcut[0] != '\0')
waddch(pad, shortcut[0]);
wattroff(pad, colorshortcut);
-}
+ }
/* bottom description */
- move(LINES-1, 2);
+ move(SCREENLINES - 1, 2);
clrtoeol();
- if (item.bottomdesc != NULL) {
- addstr(item.bottomdesc);
+ if (bottomdesc != NULL && focus) {
+ addstr(bottomdesc);
refresh();
}
}
-static void
+static int
menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- char *text, int linelen, unsigned int *menurows, int nitems,
+ const char *text, int linelen, unsigned int *menurows, int nitems,
struct buttons bs)
{
- int textrow, menusize;
-
- textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += bs.nbuttons * bs.sizebutton;
- *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
- * autosize, for example "portconfig /usr/ports/www/apache24/".
- */
- *w = MIN(*w, widget_max_width(conf)-1);
+ int htext, wtext, menusize, notext;
+
+ notext = 2;
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
+ /* algo 1): grows vertically */
+ /* notext = 1; */
+ /* algo 2): grows horizontally, better with little terminals */
+ notext += nitems;
+ notext = MIN(notext, widget_max_height(conf) - HBORDERS - 3);
+ } else
+ notext += *menurows;
+
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 6,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = HBORDERS + 2 /* buttons */ + textrow;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, linelen + 6, &bs);
+ if (rows == BSDDIALOG_AUTOSIZE) {
if (*menurows == 0) {
- *h += nitems + 2;
- *h = MIN(*h, widget_max_height(conf));
- menusize = MIN(nitems + 2, *h - (HBORDERS + 2 + textrow));
- menusize -=2;
- *menurows = menusize < 0 ? 0 : menusize;
+ menusize = widget_max_height(conf) - HBORDERS -
+ 2 /*buttons*/ - htext;
+ menusize = MIN(menusize, nitems + 2);
+ *menurows = menusize - 2 < 0 ? 0 : menusize - 2;
}
- 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 {
+ else /* h autosize with fixed menurows */
+ menusize = *menurows + 2;
+
+ *h = widget_min_height(conf, htext, menusize, true);
+ /*
+ * avoid menurows overflow and
+ * with rows=AUTOSIZE menurows!=0 becomes max-menurows
+ */
+ *menurows = MIN(*h - 6 - htext, (int)*menurows);
+ } else {
if (*menurows == 0)
- *menurows = MIN(rows-6-textrow, nitems);
+ *menurows = MIN(rows-6-htext, nitems);
}
+
+ return (0);
}
static int
-menu_checksize(int rows, int cols, char *text, int menurows, int nitems,
+menu_checksize(int rows, int cols, const char *text, int menurows, int nitems,
struct buttons bs)
{
int mincols, textrow, menusize;
@@ -499,24 +378,27 @@ menu_checksize(int rows, int cols, char *text, int menurows, int nitems,
/* buttons */
mincols += bs.nbuttons * bs.sizebutton;
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line, comment to permet some cols hidden */
+ /*
+ * linelen check, comment to allow some hidden col otherwise portconfig
+ * could not show big menus like www/apache24
+ */
/* mincols = MAX(mincols, linelen); */
if (cols < mincols)
- RETURN_ERROR("Few cols, width < size buttons or "\
- "name+descripion of the items");
+ RETURN_ERROR("Few cols, width < size buttons or "
+ "name + descripion of the items");
textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
if (nitems > 0 && menurows == 0)
- RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\
+ RETURN_ERROR("items > 0 but menurows == 0, probably terminal "
"too small");
menusize = nitems > 0 ? 3 : 0;
if (rows < 2 + 2 + menusize + textrow)
RETURN_ERROR("Few lines for this menus");
- return 0;
+ return (0);
}
/* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */
@@ -524,7 +406,6 @@ static void
update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
int totnitems, unsigned int menurows, int ymenupad)
{
-
draw_borders(conf, menuwin, h, w, LOWERED);
if (totnitems > (int) menurows) {
@@ -544,36 +425,30 @@ update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
}
static int
-do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, enum menumode mode, int ngroups,
+do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
+ unsigned int menurows, enum menumode mode, unsigned int ngroups,
struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
{
+ bool loop, onetrue, movefocus, automenurows, shortcut_butts;
+ int i, j, y, x, h, w, output, input;
+ int ymenupad, ys, ye, xs, xe, abs, next, totnitems;
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, 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 };
+ struct bsddialog_menuitem *item;
+ struct privateitem *pritems;
- shortcut_buttons = conf->menu.shortcut_buttons;
+ shortcut_butts = conf->menu.shortcut_buttons;
automenurows = menurows == BSDDIALOG_AUTOSIZE ? true : false;
totnitems = 0;
- for (i=0; i < ngroups; i++) {
- currmode = getmode(mode, groups[i]);
- if (currmode == RADIOLISTMODE)
- checkradiolist(groups[i].nitems, groups[i].items);
-
- if (currmode == MENUMODE)
- checkmenu(groups[i].nitems, groups[i].items);
-
- if (currmode == RADIOLISTMODE || currmode == CHECKLISTMODE)
+ for (i = 0; i < (int)ngroups; i++) {
+ if (getmode(mode, groups[i]) == RADIOLISTMODE ||
+ getmode(mode, groups[i]) == CHECKLISTMODE)
pos.selectorlen = 3;
- for (j=0; j < (int) groups[i].nitems; j++) {
+ for (j = 0; j < (int)groups[i].nitems; j++) {
totnitems++;
item = &groups[i].items[j];
@@ -583,7 +458,7 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
continue;
}
- pos.maxprefix = MAX(pos.maxprefix, strlen(item->prefix));
+ pos.maxprefix = MAX(pos.maxprefix,strlen(item->prefix));
pos.maxdepth = MAX(pos.maxdepth, item->depth);
pos.maxname = MAX(pos.maxname, strlen(item->name));
pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc));
@@ -594,30 +469,33 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
pos.maxdepth *= DEPTHSPACE;
pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0);
- pos.xname = pos.xselector + pos.selectorlen + (pos.selectorlen > 0 ? 1 : 0);
+ pos.xname = pos.xselector + pos.selectorlen +
+ (pos.selectorlen > 0 ? 1 : 0);
pos.xdesc = pos.maxdepth + pos.xname + pos.maxname;
pos.xdesc += (pos.maxname != 0 ? 1 : 0);
pos.line = MAX(pos.maxsepstr + 3, pos.xdesc + pos.maxdesc);
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- menu_autosize(conf, rows, cols, &h, &w, text, pos.line, &menurows,
- totnitems, bs);
+ return (BSDDIALOG_ERROR);
+ if (menu_autosize(conf, rows, cols, &h, &w, text, pos.line, &menurows,
+ totnitems, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (menu_checksize(h, w, text, menurows, totnitems, 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_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ shortcut_butts) != 0)
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ doupdate();
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - menurows, x + 1 + w - TEXTHMARGIN);
menuwin = new_boxed_window(conf, y + h - 5 - menurows, x + 2,
menurows+2, w-4, LOWERED);
@@ -625,138 +503,143 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
menupad = newpad(totnitems, pos.line);
wbkgd(menupad, t.dialog.color);
- ymenupad = 0;
- for (i=0; i<ngroups; i++) {
- currmode = getmode(mode, groups[i]);
- for (j=0; j < (int) groups[i].nitems; j++) {
+ if ((pritems = calloc(totnitems, sizeof (struct privateitem))) == NULL)
+ RETURN_ERROR("Cannot allocate memory for internal menu items");
+
+ abs = 0;
+ for (i = 0; i < (int)ngroups; i++) {
+ onetrue = false;
+ for (j = 0; j < (int)groups[i].nitems; j++) {
item = &groups[i].items[j];
- drawitem(conf, menupad, ymenupad, *item, currmode, pos,
- false);
- ymenupad++;
+
+ if (getmode(mode, groups[i]) == MENUMODE) {
+ pritems[abs].on = false;
+ } else if (getmode(mode, groups[i]) == RADIOLISTMODE) {
+ pritems[abs].on = onetrue ? false : item->on;
+ if (pritems[abs].on)
+ onetrue = true;
+ } else {
+ pritems[abs].on = item->on;
+ }
+ pritems[abs].group = i;
+ pritems[abs].index = j;
+ pritems[abs].type = getmode(mode, groups[i]);
+ pritems[abs].item = item;
+
+ drawitem(conf, menupad, abs, pos, &pritems[abs], false);
+ abs++;
}
}
- 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);
+ abs = getfirst_with_default(totnitems, pritems, ngroups, groups,
+ focuslist, focusitem);
+ if (abs >= 0)
+ drawitem(conf, menupad, abs, pos, &pritems[abs], true);
ys = y + h - 5 - menurows + 1;
ye = y + h - 5 ;
if (conf->menu.align_left || (int)pos.line > w - 6) {
xs = x + 3;
xe = xs + w - 7;
- }
- else { /* center */
+ } else { /* center */
xs = x + 3 + (w-6)/2 - pos.line/2;
xe = xs + w - 5;
}
- ymenupad = 0; /* now ymenupad is pminrow for prefresh() */
+ ymenupad = 0;
if ((int)(ymenupad + menurows) - 1 < abs)
ymenupad = abs - menurows + 1;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, menurows, ymenupad);
+ update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, menurows,
+ ymenupad);
wrefresh(menuwin);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
-
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
- wrefresh(widget);
+ movefocus = false;
loop = true;
- while(loop) {
+ while (loop) {
input = getch();
switch(input) {
case KEY_ENTER:
case 10: /* Enter */
output = bs.value[bs.curr];
- if (currmode == MENUMODE)
- item->on = true;
+ if (abs >= 0 && pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups, groups, pritems);
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ if (abs >= 0 && pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups, groups,
+ pritems);
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
break;
case KEY_LEFT:
if (bs.curr > 0) {
bs.curr--;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
}
break;
case KEY_RIGHT:
if (bs.curr < (int) bs.nbuttons - 1) {
bs.curr++;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
}
break;
- case KEY_CTRL('E'): /* add conf->menu.extrahelpkey ? */
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;
+ return (BSDDIALOG_ERROR);
menurows = automenurows ? 0 : menurows;
- menu_autosize(conf, rows, cols, &h, &w, text, pos.line,
- &menurows, totnitems, bs);
- if (menu_checksize(h, w, text, menurows, totnitems, bs) != 0)
- return BSDDIALOG_ERROR;
+ if (menu_autosize(conf, rows, cols, &h, &w, text,
+ pos.line, &menurows, totnitems, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (menu_checksize(h, w, text, menurows, totnitems,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- 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);
+ return (BSDDIALOG_ERROR);
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, shortcut_butts) != 0)
+ return (BSDDIALOG_ERROR);
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
- wrefresh(widget);
+ doupdate();
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - menurows, x + 1 + w - TEXTHMARGIN);
wclear(menuwin);
mvwin(menuwin, y + h - 5 - menurows, x + 2);
wresize(menuwin,menurows+2, w-4);
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
+ update_menuwin(conf, menuwin, menurows+2, w-4,
+ totnitems, menurows, ymenupad);
wrefresh(menuwin);
-
+
ys = y + h - 5 - menurows + 1;
ye = y + h - 5 ;
if (conf->menu.align_left || (int)pos.line > w - 6) {
xs = x + 3;
xe = xs + w - 7;
- }
- else { /* center */
+ } else { /* center */
xs = x + 3 + (w-6)/2 - pos.line/2;
xe = xs + w - 5;
}
@@ -774,385 +657,153 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
continue;
switch(input) {
case KEY_HOME:
+ next = getnext(totnitems, pritems, -1);
+ movefocus = next != abs;
+ break;
case KEY_UP:
+ next = getprev(pritems, abs);
+ movefocus = next != abs;
+ break;
case KEY_PPAGE:
- if (abs == 0) /* useless, just to save cpu refresh */
- break;
- drawitem(conf, menupad, abs, *item, currmode, pos, false);
- if (input == KEY_HOME)
- getfirst(ngroups, groups, &abs, &g, &rel);
- else if (input == KEY_UP)
- getprev(groups, &abs, &g, &rel);
- else /* input == KEY_PPAGE*/
- getfastprev(menurows, groups, &abs, &g, &rel);
- 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;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
- wrefresh(menuwin);
- prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ next = getfastprev(menurows, pritems, abs);
+ movefocus = next != abs;
break;
case KEY_END:
+ next = getprev(pritems, totnitems);
+ movefocus = next != abs;
+ break;
case KEY_DOWN:
+ next = getnext(totnitems, pritems, abs);
+ movefocus = next != abs;
+ break;
case KEY_NPAGE:
- if (abs == totnitems -1)
- break; /* useless, just to save cpu refresh */
- drawitem(conf, menupad, abs, *item, currmode, pos, false);
- if (input == KEY_END)
- getlast(totnitems, ngroups, groups, &abs, &g, &rel);
- else if (input == KEY_DOWN)
- getnext(ngroups, groups, &abs, &g, &rel);
- else /* input == KEY_NPAGE*/
- getfastnext(menurows, ngroups, groups, &abs, &g, &rel);
- item = &groups[g].items[rel];
- currmode= getmode(mode, groups[g]);
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
- 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);
+ next = getfastnext(menurows, totnitems, pritems, abs);
+ movefocus = next != abs;
break;
case ' ': /* Space */
- if (currmode == MENUMODE)
+ if (pritems[abs].type == MENUMODE)
break;
- else if (currmode == CHECKLISTMODE)
- item->on = !item->on;
+ else if (pritems[abs].type == CHECKLISTMODE)
+ pritems[abs].on = !pritems[abs].on;
else { /* RADIOLISTMODE */
- for (i=0; i < (int) groups[g].nitems; i++)
- if (groups[g].items[i].on == true && i != rel) {
- groups[g].items[i].on = false;
- drawitem(conf, menupad,
- abs - rel + i, groups[g].items[i],
- currmode, pos, false);
+ for (i = abs - pritems[abs].index;
+ i < totnitems &&
+ pritems[i].group == pritems[abs].group;
+ i++) {
+ if (i != abs && pritems[i].on) {
+ pritems[i].on = false;
+ drawitem(conf, menupad, i, pos,
+ &pritems[i], false);
}
- item->on = !item->on;
+ }
+ pritems[abs].on = !pritems[abs].on;
}
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
+ drawitem(conf, menupad, abs, pos, &pritems[abs], true);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ break;
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;
- }
+ if (shortcut_butts) {
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ if (pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups,
+ groups, pritems);
+ 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);
+ /* shourtcut items */
+ next = getnextshortcut(conf, totnitems, pritems, abs,
+ input);
+ movefocus = next != abs;
+ }
+
+ if (movefocus) {
+ drawitem(conf, menupad, abs, pos, &pritems[abs], false);
+ abs = next;
+ drawitem(conf, menupad, abs, pos, &pritems[abs], 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);
+ update_menuwin(conf, menuwin, menurows+2, w-4,
+ totnitems, menurows, ymenupad);
wrefresh(menuwin);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ movefocus = false;
}
}
if (focuslist != NULL)
- *focuslist = g;
+ *focuslist = abs < 0 ? -1 : pritems[abs].group;
if (focusitem !=NULL)
- *focusitem = rel;
+ *focusitem = abs < 0 ? -1 : pritems[abs].index;
delwin(menupad);
delwin(menuwin);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
+ free(pritems);
- return output;
+ return (output);
}
-/*
- * API
- */
-
-int bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups,
- int *focuslist, int *focusitem)
+/* API */
+int
+bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int ngroups,
+ struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
{
int output;
output = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE,
ngroups, groups, focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE,
- 1, &group, NULL, focusitem);
+ 1, &group, &focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1,
- &group, NULL, focusitem);
+ &group, &focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_RADIOLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE,
- 1, &group, NULL, focusitem);
-
- return output;
-}
-
-/* todo */
-static int buildlist_autosize(int rows, int cols)
-{
-
- if (cols == BSDDIALOG_AUTOSIZE)
- RETURN_ERROR("Unimplemented cols autosize for buildlist");
-
- if (rows == BSDDIALOG_AUTOSIZE)
- RETURN_ERROR("Unimplemented rows autosize for buildlist");
-
- return 0;
-}
-
-/* to improve */
-static int
-buildlist_checksize(int rows, int cols, char *text, int menurows, int nitems,
- struct buttons bs)
-{
- int mincols, textrow, menusize;
-
- mincols = VBORDERS;
- /* buttons */
- mincols += bs.nbuttons * bs.sizebutton;
- mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line, comment to permet some cols hidden */
- /* mincols = MAX(mincols, linelen); */
+ 1, &group, &focuslist, focusitem);
- if (cols < mincols)
- RETURN_ERROR("Few cols, width < size buttons or "\
- "name+descripion of the items");
-
- textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
-
- if (nitems > 0 && menurows == 0)
- RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\
- "too small");
-
- menusize = nitems > 0 ? 3 : 0;
- if (rows < 2 + 2 + menusize + textrow)
- RETURN_ERROR("Few lines for this menus");
-
- return 0;
-}
-
-int
-bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
-{
- WINDOW *widget, *textpad, *leftwin, *leftpad, *rightwin, *rightpad, *shadow;
- int output, i, x, y, h, w, htextpad, input;
- bool loop, buttupdate, padsupdate, startleft;
- int nlefts, nrights, leftwinx, rightwinx, winsy, padscols, curr;
- enum side {LEFT, RIGHT} currV;
- int currH;
- struct buttons bs;
- struct lineposition pos = {0,0,0,0,0,0,0,0,0,0};
-
- startleft = false;
- for (i=0; i<nitems; i++) {
- pos.line = MAX(pos.line, strlen(items[i].desc));
- if (items[i].on == false)
- startleft = true;
- }
-
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (buildlist_autosize(rows, cols) != 0)
- return BSDDIALOG_ERROR;
- if (buildlist_checksize(h, w, text, menurows, nitems, bs) != 0)
- return BSDDIALOG_ERROR;
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
-
- winsy = y + h - 5 - menurows;
- leftwinx = x+2;
- leftwin = new_boxed_window(conf, winsy, leftwinx, menurows+2, (w-5)/2,
- LOWERED);
- rightwinx = x + w - 2 -(w-5)/2;
- rightwin = new_boxed_window(conf, winsy, rightwinx, menurows+2,
- (w-5)/2, LOWERED);
-
- wrefresh(leftwin);
- wrefresh(rightwin);
-
- padscols = (w-5)/2 - 2;
- leftpad = newpad(nitems, pos.line);
- rightpad = newpad(nitems, pos.line);
- wbkgd(leftpad, t.dialog.color);
- wbkgd(rightpad, t.dialog.color);
-
- currH = 0;
- currV = startleft ? LEFT : RIGHT;
- loop = buttupdate = padsupdate = true;
- while(loop) {
- if (buttupdate) {
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- buttupdate = false;
- }
-
- if (padsupdate) {
- werase(leftpad);
- werase(rightpad);
- curr = -1;
- nlefts = nrights = 0;
- for (i=0; i<nitems; i++) {
- if (items[i].on == false) {
- if (currV == LEFT && currH == nlefts)
- curr = i;
- drawitem(conf, leftpad, nlefts, items[i],
- BUILDLISTMODE, pos, curr == i);
- nlefts++;
- } else {
- if (currV == RIGHT && currH == nrights)
- curr = i;
- drawitem(conf, rightpad, nrights, items[i],
- BUILDLISTMODE, pos, curr == i);
- nrights++;
- }
- }
- prefresh(leftpad, 0, 0, winsy+1, leftwinx+1,
- winsy+1+menurows, leftwinx + 1 + padscols);
- prefresh(rightpad, 0, 0, winsy+1, rightwinx+1,
- winsy+1+menurows, rightwinx + 1 + padscols);
- padsupdate = false;
- }
-
- input = getch();
- switch(input) {
- case KEY_ENTER:
- case 10: /* Enter */
- output = bs.value[bs.curr];
- loop = false;
- break;
- case 27: /* Esc */
- output = BSDDIALOG_ERROR;
- loop = false;
- break;
- case '\t': /* TAB */
- bs.curr = (bs.curr + 1) % bs.nbuttons;
- buttupdate = true;
- break;
- }
-
- if (nitems <= 0)
- continue;
-
- switch(input) {
- case KEY_LEFT:
- if (currV == RIGHT && nrights > 0) {
- currV = LEFT;
- currH = 0;
- padsupdate = true;
- }
- break;
- case KEY_RIGHT:
- if (currV == LEFT && nrights > 0) {
- currV = RIGHT;
- currH = 0;
- padsupdate = true;
- }
- break;
- case KEY_UP:
- currH = (currH > 0) ? currH - 1 : 0;
- padsupdate = true;
- break;
- case KEY_DOWN:
- if (currV == LEFT)
- currH = (currH < nlefts-1) ? currH +1 : currH;
- else
- currH = (currH < nrights-1)? currH +1 : currH;
- padsupdate = true;
- break;
- case ' ': /* Space */
- items[curr].on = ! items[curr].on;
- if (currV == LEFT) {
- if (nlefts > 1)
- currH = currH > 0 ? currH-1 : 0;
- else {
- currH = 0;
- currV = RIGHT;
- }
- } else {
- if (nrights > 1)
- currH = currH > 0 ? currH-1 : 0;
- else {
- currH = 0;
- currV = LEFT;
- }
- }
- padsupdate = true;
- break;
- default:
-
- break;
- }
- }
-
- if(focusitem != NULL)
- *focusitem = curr;
-
- delwin(leftpad);
- delwin(leftwin);
- delwin(rightpad);
- delwin(rightwin);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
-
- return output;
-}
+ return (output);
+} \ No newline at end of file