1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4*a6d8be45SAlfonso S. Siciliano * Copyright (c) 2021-2024 Alfonso Sabato Siciliano 5c76f0793SBaptiste Daroussin * 6c76f0793SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7c76f0793SBaptiste Daroussin * modification, are permitted provided that the following conditions 8c76f0793SBaptiste Daroussin * are met: 9c76f0793SBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 11c76f0793SBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 12c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 13c76f0793SBaptiste Daroussin * documentation and/or other materials provided with the distribution. 14c76f0793SBaptiste Daroussin * 15c76f0793SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16c76f0793SBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c76f0793SBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c76f0793SBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19c76f0793SBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c76f0793SBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c76f0793SBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c76f0793SBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c76f0793SBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c76f0793SBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c76f0793SBaptiste Daroussin * SUCH DAMAGE. 26c76f0793SBaptiste Daroussin */ 27c76f0793SBaptiste Daroussin 28263660c0SAlfonso Siciliano #include <curses.h> 29263660c0SAlfonso Siciliano #include <stdlib.h> 30d93b4d32SBaptiste Daroussin 31c76f0793SBaptiste Daroussin #include "bsddialog.h" 32c76f0793SBaptiste Daroussin #include "bsddialog_theme.h" 33263660c0SAlfonso Siciliano #include "lib_util.h" 34c76f0793SBaptiste Daroussin 35c76f0793SBaptiste Daroussin enum menumode { 36c76f0793SBaptiste Daroussin CHECKLISTMODE, 37c76f0793SBaptiste Daroussin MENUMODE, 38c76f0793SBaptiste Daroussin MIXEDLISTMODE, 39c76f0793SBaptiste Daroussin RADIOLISTMODE, 40c76f0793SBaptiste Daroussin SEPARATORMODE 41c76f0793SBaptiste Daroussin }; 42c76f0793SBaptiste Daroussin 43263660c0SAlfonso Siciliano struct privateitem { 4461ba55bcSBaptiste Daroussin const char *prefix; 4561ba55bcSBaptiste Daroussin bool on; /* menu changes, not API on */ 4661ba55bcSBaptiste Daroussin unsigned int depth; 4761ba55bcSBaptiste Daroussin const char *name; 4861ba55bcSBaptiste Daroussin const char *desc; 4961ba55bcSBaptiste Daroussin const char *bottomdesc; 5061ba55bcSBaptiste Daroussin int group; /* index menu in menugroup */ 5161ba55bcSBaptiste Daroussin int index; /* real item index inside its menu */ 52263660c0SAlfonso Siciliano enum menumode type; 5361ba55bcSBaptiste Daroussin wchar_t shortcut; 54263660c0SAlfonso Siciliano }; 55c76f0793SBaptiste Daroussin 5661ba55bcSBaptiste Daroussin struct privatemenu { 5761ba55bcSBaptiste Daroussin WINDOW *box; /* only for borders */ 5861ba55bcSBaptiste Daroussin WINDOW *pad; /* pad for the private items */ 5961ba55bcSBaptiste Daroussin int ypad; /* start pad line */ 6061ba55bcSBaptiste Daroussin int ys, ye, xs, xe; /* pad pos */ 6161ba55bcSBaptiste Daroussin unsigned int xselector; /* [] */ 6261ba55bcSBaptiste Daroussin unsigned int xname; /* real x: xname + item.depth */ 6361ba55bcSBaptiste Daroussin unsigned int xdesc; /* real x: xdesc + item.depth */ 6461ba55bcSBaptiste Daroussin unsigned int line; /* wpad: prefix [] depth name desc */ 6561ba55bcSBaptiste Daroussin unsigned int apimenurows; 6661ba55bcSBaptiste Daroussin unsigned int menurows; /* real menurows after menu_size_position() */ 6761ba55bcSBaptiste Daroussin int nitems; /* total nitems (all groups * all items) */ 6861ba55bcSBaptiste Daroussin struct privateitem *pritems; 6961ba55bcSBaptiste Daroussin int sel; /* current focus item, can be -1 */ 7061ba55bcSBaptiste Daroussin bool hasbottomdesc; 7161ba55bcSBaptiste Daroussin }; 7261ba55bcSBaptiste Daroussin 7361ba55bcSBaptiste Daroussin static enum menumode 7461ba55bcSBaptiste Daroussin getmode(enum menumode mode, struct bsddialog_menugroup group) 75263660c0SAlfonso Siciliano { 7661ba55bcSBaptiste Daroussin if (mode == MIXEDLISTMODE) { 7761ba55bcSBaptiste Daroussin if (group.type == BSDDIALOG_SEPARATOR) 7861ba55bcSBaptiste Daroussin mode = SEPARATORMODE; 7961ba55bcSBaptiste Daroussin else if (group.type == BSDDIALOG_RADIOLIST) 8061ba55bcSBaptiste Daroussin mode = RADIOLISTMODE; 8161ba55bcSBaptiste Daroussin else if (group.type == BSDDIALOG_CHECKLIST) 8261ba55bcSBaptiste Daroussin mode = CHECKLISTMODE; 8361ba55bcSBaptiste Daroussin } 8461ba55bcSBaptiste Daroussin 8561ba55bcSBaptiste Daroussin return (mode); 8661ba55bcSBaptiste Daroussin } 8761ba55bcSBaptiste Daroussin 8861ba55bcSBaptiste Daroussin static int 8961ba55bcSBaptiste Daroussin build_privatemenu(struct bsddialog_conf *conf, struct privatemenu *m, 9061ba55bcSBaptiste Daroussin enum menumode mode, unsigned int ngroups, 9161ba55bcSBaptiste Daroussin struct bsddialog_menugroup *groups) 9261ba55bcSBaptiste Daroussin { 9361ba55bcSBaptiste Daroussin bool onetrue; 94263660c0SAlfonso Siciliano int i, j, abs; 9561ba55bcSBaptiste Daroussin unsigned int maxsepstr, maxprefix, selectorlen, maxdepth; 9661ba55bcSBaptiste Daroussin unsigned int maxname, maxdesc; 9761ba55bcSBaptiste Daroussin struct bsddialog_menuitem *item; 9861ba55bcSBaptiste Daroussin struct privateitem *pritem; 99263660c0SAlfonso Siciliano 10061ba55bcSBaptiste Daroussin /* nitems and fault checks */ 10161ba55bcSBaptiste Daroussin CHECK_ARRAY(ngroups, groups); 10261ba55bcSBaptiste Daroussin m->nitems = 0; 10361ba55bcSBaptiste Daroussin for (i = 0; i < (int)ngroups; i++) { 10461ba55bcSBaptiste Daroussin CHECK_ARRAY(groups[i].nitems, groups[i].items); 10561ba55bcSBaptiste Daroussin m->nitems += (int)groups[i].nitems; 10661ba55bcSBaptiste Daroussin } 107c76f0793SBaptiste Daroussin 10861ba55bcSBaptiste Daroussin /* alloc and set private items */ 10961ba55bcSBaptiste Daroussin m->pritems = calloc(m->nitems, sizeof (struct privateitem)); 11061ba55bcSBaptiste Daroussin if (m->pritems == NULL) 11161ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot allocate memory for internal menu items"); 11261ba55bcSBaptiste Daroussin m->hasbottomdesc = false; 11361ba55bcSBaptiste Daroussin abs = 0; 11461ba55bcSBaptiste Daroussin for (i = 0; i < (int)ngroups; i++) { 11561ba55bcSBaptiste Daroussin onetrue = false; 11661ba55bcSBaptiste Daroussin for (j = 0; j < (int)groups[i].nitems; j++) { 11761ba55bcSBaptiste Daroussin item = &groups[i].items[j]; 11861ba55bcSBaptiste Daroussin pritem = &m->pritems[abs]; 11961ba55bcSBaptiste Daroussin 12061ba55bcSBaptiste Daroussin if (getmode(mode, groups[i]) == MENUMODE) { 12161ba55bcSBaptiste Daroussin m->pritems[abs].on = false; 12261ba55bcSBaptiste Daroussin } else if (getmode(mode, groups[i]) == RADIOLISTMODE) { 12361ba55bcSBaptiste Daroussin m->pritems[abs].on = onetrue ? false : item->on; 12461ba55bcSBaptiste Daroussin if (m->pritems[abs].on) 12561ba55bcSBaptiste Daroussin onetrue = true; 12661ba55bcSBaptiste Daroussin } else { /* CHECKLISTMODE */ 12761ba55bcSBaptiste Daroussin m->pritems[abs].on = item->on; 12861ba55bcSBaptiste Daroussin } 12961ba55bcSBaptiste Daroussin pritem->group = i; 13061ba55bcSBaptiste Daroussin pritem->index = j; 13161ba55bcSBaptiste Daroussin pritem->type = getmode(mode, groups[i]); 13261ba55bcSBaptiste Daroussin 13361ba55bcSBaptiste Daroussin pritem->prefix = CHECK_STR(item->prefix); 13461ba55bcSBaptiste Daroussin pritem->depth = item->depth; 13561ba55bcSBaptiste Daroussin pritem->name = CHECK_STR(item->name); 13661ba55bcSBaptiste Daroussin pritem->desc = CHECK_STR(item->desc); 13761ba55bcSBaptiste Daroussin pritem->bottomdesc = CHECK_STR(item->bottomdesc); 13861ba55bcSBaptiste Daroussin if (item->bottomdesc != NULL) 13961ba55bcSBaptiste Daroussin m->hasbottomdesc = true; 14061ba55bcSBaptiste Daroussin 14161ba55bcSBaptiste Daroussin mbtowc(&pritem->shortcut, conf->menu.no_name ? 14261ba55bcSBaptiste Daroussin pritem->desc : pritem->name, MB_CUR_MAX); 14361ba55bcSBaptiste Daroussin 14461ba55bcSBaptiste Daroussin abs++; 14561ba55bcSBaptiste Daroussin } 14661ba55bcSBaptiste Daroussin } 14761ba55bcSBaptiste Daroussin 14861ba55bcSBaptiste Daroussin /* positions */ 14961ba55bcSBaptiste Daroussin m->xselector = m->xname = m->xdesc = m->line = 0; 15061ba55bcSBaptiste Daroussin maxsepstr = maxprefix = selectorlen = maxdepth = maxname = maxdesc = 0; 15161ba55bcSBaptiste Daroussin for (i = 0; i < m->nitems; i++) { 15261ba55bcSBaptiste Daroussin if (m->pritems[i].type == RADIOLISTMODE || 15361ba55bcSBaptiste Daroussin m->pritems[i].type == CHECKLISTMODE) 15461ba55bcSBaptiste Daroussin selectorlen = 4; 15561ba55bcSBaptiste Daroussin 15661ba55bcSBaptiste Daroussin if (m->pritems[i].type == SEPARATORMODE) { 15761ba55bcSBaptiste Daroussin maxsepstr = MAX(maxsepstr, 15861ba55bcSBaptiste Daroussin strcols(m->pritems[i].name) + 15961ba55bcSBaptiste Daroussin strcols(m->pritems[i].desc)); 160c76f0793SBaptiste Daroussin continue; 161c76f0793SBaptiste Daroussin } 162263660c0SAlfonso Siciliano 16361ba55bcSBaptiste Daroussin maxprefix = MAX(maxprefix, strcols(m->pritems[i].prefix)); 16461ba55bcSBaptiste Daroussin maxdepth = MAX(maxdepth, m->pritems[i].depth); 16561ba55bcSBaptiste Daroussin maxname = MAX(maxname, strcols(m->pritems[i].name)); 16661ba55bcSBaptiste Daroussin maxdesc = MAX(maxdesc, strcols(m->pritems[i].desc)); 167c76f0793SBaptiste Daroussin } 16861ba55bcSBaptiste Daroussin maxname = conf->menu.no_name ? 0 : maxname; 16961ba55bcSBaptiste Daroussin maxdesc = conf->menu.no_desc ? 0 : maxdesc; 17061ba55bcSBaptiste Daroussin 17161ba55bcSBaptiste Daroussin m->xselector = maxprefix + (maxprefix != 0 ? 1 : 0); 17261ba55bcSBaptiste Daroussin m->xname = m->xselector + selectorlen; 17361ba55bcSBaptiste Daroussin m->xdesc = maxdepth + m->xname + maxname; 17461ba55bcSBaptiste Daroussin m->xdesc += (maxname != 0 ? 1 : 0); 17561ba55bcSBaptiste Daroussin m->line = MAX(maxsepstr + 3, m->xdesc + maxdesc); 17661ba55bcSBaptiste Daroussin 17761ba55bcSBaptiste Daroussin return (0); 17861ba55bcSBaptiste Daroussin } 17961ba55bcSBaptiste Daroussin 18061ba55bcSBaptiste Daroussin static void 18161ba55bcSBaptiste Daroussin set_return_on(struct privatemenu *m, struct bsddialog_menugroup *groups) 18261ba55bcSBaptiste Daroussin { 18361ba55bcSBaptiste Daroussin int i; 18461ba55bcSBaptiste Daroussin struct privateitem *pritem; 18561ba55bcSBaptiste Daroussin 18661ba55bcSBaptiste Daroussin for (i = 0; i < m->nitems; i++) { 18761ba55bcSBaptiste Daroussin if (m->pritems[i].type == SEPARATORMODE) 18861ba55bcSBaptiste Daroussin continue; 18961ba55bcSBaptiste Daroussin pritem = &m->pritems[i]; 19061ba55bcSBaptiste Daroussin groups[pritem->group].items[pritem->index].on = pritem->on; 191c76f0793SBaptiste Daroussin } 192c76f0793SBaptiste Daroussin } 193c76f0793SBaptiste Daroussin 194263660c0SAlfonso Siciliano static int getprev(struct privateitem *pritems, int abs) 195c76f0793SBaptiste Daroussin { 196263660c0SAlfonso Siciliano int i; 197c76f0793SBaptiste Daroussin 198263660c0SAlfonso Siciliano for (i = abs - 1; i >= 0; i--) { 199263660c0SAlfonso Siciliano if (pritems[i].type == SEPARATORMODE) 200c76f0793SBaptiste Daroussin continue; 201263660c0SAlfonso Siciliano return (i); 202c76f0793SBaptiste Daroussin } 203c76f0793SBaptiste Daroussin 204263660c0SAlfonso Siciliano return (abs); 205263660c0SAlfonso Siciliano } 206263660c0SAlfonso Siciliano 207263660c0SAlfonso Siciliano static int getnext(int npritems, struct privateitem *pritems, int abs) 208c76f0793SBaptiste Daroussin { 209263660c0SAlfonso Siciliano int i; 210c76f0793SBaptiste Daroussin 211263660c0SAlfonso Siciliano for (i = abs + 1; i < npritems; i++) { 212263660c0SAlfonso Siciliano if (pritems[i].type == SEPARATORMODE) 213c76f0793SBaptiste Daroussin continue; 214263660c0SAlfonso Siciliano return (i); 215c76f0793SBaptiste Daroussin } 216c76f0793SBaptiste Daroussin 217263660c0SAlfonso Siciliano return (abs); 218263660c0SAlfonso Siciliano } 219263660c0SAlfonso Siciliano 220263660c0SAlfonso Siciliano static int 221263660c0SAlfonso Siciliano getfirst_with_default(int npritems, struct privateitem *pritems, int ngroups, 222263660c0SAlfonso Siciliano struct bsddialog_menugroup *groups, int *focusgroup, int *focusitem) 223263660c0SAlfonso Siciliano { 224263660c0SAlfonso Siciliano int i, abs; 225263660c0SAlfonso Siciliano 226263660c0SAlfonso Siciliano if ((abs = getnext(npritems, pritems, -1)) < 0) 227263660c0SAlfonso Siciliano return (abs); 228263660c0SAlfonso Siciliano 229263660c0SAlfonso Siciliano if (focusgroup == NULL || focusitem == NULL) 230263660c0SAlfonso Siciliano return (abs); 231263660c0SAlfonso Siciliano if (*focusgroup < 0 || *focusgroup >= ngroups) 232263660c0SAlfonso Siciliano return (abs); 233263660c0SAlfonso Siciliano if (groups[*focusgroup].type == BSDDIALOG_SEPARATOR) 234263660c0SAlfonso Siciliano return (abs); 235263660c0SAlfonso Siciliano if (*focusitem < 0 || *focusitem >= (int)groups[*focusgroup].nitems) 236263660c0SAlfonso Siciliano return (abs); 237263660c0SAlfonso Siciliano 238263660c0SAlfonso Siciliano for (i = abs; i < npritems; i++) { 239263660c0SAlfonso Siciliano if (pritems[i].group == *focusgroup && 240263660c0SAlfonso Siciliano pritems[i].index == *focusitem) 241263660c0SAlfonso Siciliano return (i); 242263660c0SAlfonso Siciliano } 243263660c0SAlfonso Siciliano 244263660c0SAlfonso Siciliano return (abs); 245263660c0SAlfonso Siciliano } 246263660c0SAlfonso Siciliano 247263660c0SAlfonso Siciliano static int 248263660c0SAlfonso Siciliano getfastnext(int menurows, int npritems, struct privateitem *pritems, int abs) 249c76f0793SBaptiste Daroussin { 250c76f0793SBaptiste Daroussin int a, start, i; 251c76f0793SBaptiste Daroussin 252263660c0SAlfonso Siciliano start = abs; 253c76f0793SBaptiste Daroussin i = menurows; 254c76f0793SBaptiste Daroussin do { 255263660c0SAlfonso Siciliano a = abs; 256263660c0SAlfonso Siciliano abs = getnext(npritems, pritems, abs); 257c76f0793SBaptiste Daroussin i--; 258263660c0SAlfonso Siciliano } while (abs != a && abs < start + menurows && i > 0); 259263660c0SAlfonso Siciliano 260263660c0SAlfonso Siciliano return (abs); 261c76f0793SBaptiste Daroussin } 262c76f0793SBaptiste Daroussin 263263660c0SAlfonso Siciliano static int 264263660c0SAlfonso Siciliano getfastprev(int menurows, struct privateitem *pritems, int abs) 265c76f0793SBaptiste Daroussin { 266c76f0793SBaptiste Daroussin int a, start, i; 267c76f0793SBaptiste Daroussin 268263660c0SAlfonso Siciliano start = abs; 269c76f0793SBaptiste Daroussin i = menurows; 270c76f0793SBaptiste Daroussin do { 271263660c0SAlfonso Siciliano a = abs; 272263660c0SAlfonso Siciliano abs = getprev(pritems, abs); 273c76f0793SBaptiste Daroussin i--; 274263660c0SAlfonso Siciliano } while (abs != a && abs > start - menurows && i > 0); 275263660c0SAlfonso Siciliano 276263660c0SAlfonso Siciliano return (abs); 277c76f0793SBaptiste Daroussin } 278c76f0793SBaptiste Daroussin 279263660c0SAlfonso Siciliano static int 28061ba55bcSBaptiste Daroussin getnextshortcut(int npritems, struct privateitem *pritems, int abs, wint_t key) 2818c4f4028SBaptiste Daroussin { 282b319d934SAlfonso S. Siciliano int i, next; 2838c4f4028SBaptiste Daroussin 284263660c0SAlfonso Siciliano next = -1; 285263660c0SAlfonso Siciliano for (i = 0; i < npritems; i++) { 286263660c0SAlfonso Siciliano if (pritems[i].type == SEPARATORMODE) 2878c4f4028SBaptiste Daroussin continue; 28861ba55bcSBaptiste Daroussin if (pritems[i].shortcut == (wchar_t)key) { 289263660c0SAlfonso Siciliano if (i > abs) 290263660c0SAlfonso Siciliano return (i); 291263660c0SAlfonso Siciliano if (i < abs && next == -1) 292263660c0SAlfonso Siciliano next = i; 2938c4f4028SBaptiste Daroussin } 2948c4f4028SBaptiste Daroussin } 2958c4f4028SBaptiste Daroussin 296263660c0SAlfonso Siciliano return (next != -1 ? next : abs); 2978c4f4028SBaptiste Daroussin } 2988c4f4028SBaptiste Daroussin 29961ba55bcSBaptiste Daroussin static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m) 300c76f0793SBaptiste Daroussin { 301*a6d8be45SAlfonso S. Siciliano int i, realw, labellen; 302bce40c02SAlfonso S. Siciliano const char *desc, *name; 303263660c0SAlfonso Siciliano 30461ba55bcSBaptiste Daroussin for (i = 0; i < m->nitems; i++) { 30561ba55bcSBaptiste Daroussin if (m->pritems[i].type != SEPARATORMODE) 306bce40c02SAlfonso S. Siciliano continue; 307f499134dSBaptiste Daroussin if (conf->no_lines == false) { 30861ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.desccolor); 309*a6d8be45SAlfonso S. Siciliano if (conf->ascii_lines) 310*a6d8be45SAlfonso S. Siciliano mvwhline(m->pad, i, 0, '-', m->line); 311*a6d8be45SAlfonso S. Siciliano else 312*a6d8be45SAlfonso S. Siciliano mvwhline_set(m->pad, i, 0, WACS_HLINE, m->line); 31361ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.desccolor); 314c76f0793SBaptiste Daroussin } 31561ba55bcSBaptiste Daroussin name = m->pritems[i].name; 31661ba55bcSBaptiste Daroussin desc = m->pritems[i].desc; 31761ba55bcSBaptiste Daroussin realw = m->xe - m->xs; 318b319d934SAlfonso S. Siciliano labellen = strcols(name) + strcols(desc) + 1; 31961ba55bcSBaptiste Daroussin wmove(m->pad, i, (labellen < realw) ? realw/2 - labellen/2 : 0); 32061ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.sepnamecolor); 32161ba55bcSBaptiste Daroussin waddstr(m->pad, name); 32261ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.sepnamecolor); 323b319d934SAlfonso S. Siciliano if (strcols(name) > 0 && strcols(desc) > 0) 32461ba55bcSBaptiste Daroussin waddch(m->pad, ' '); 32561ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.sepdesccolor); 32661ba55bcSBaptiste Daroussin waddstr(m->pad, desc); 32761ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.sepdesccolor); 328bce40c02SAlfonso S. Siciliano } 329c76f0793SBaptiste Daroussin } 330c76f0793SBaptiste Daroussin 331bce40c02SAlfonso S. Siciliano static void 33261ba55bcSBaptiste Daroussin drawitem(struct bsddialog_conf *conf, struct privatemenu *m, int y, bool focus) 333bce40c02SAlfonso S. Siciliano { 334bce40c02SAlfonso S. Siciliano int colordesc, colorname, colorshortcut; 33561ba55bcSBaptiste Daroussin struct privateitem *pritem; 336bce40c02SAlfonso S. Siciliano 33761ba55bcSBaptiste Daroussin pritem = &m->pritems[y]; 338bce40c02SAlfonso S. Siciliano 339c76f0793SBaptiste Daroussin /* prefix */ 34061ba55bcSBaptiste Daroussin wattron(m->pad, focus ? t.menu.f_prefixcolor : t.menu.prefixcolor); 34161ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, 0, pritem->prefix); 34261ba55bcSBaptiste Daroussin wattroff(m->pad, focus ? t.menu.f_prefixcolor : t.menu.prefixcolor); 343c76f0793SBaptiste Daroussin 344c76f0793SBaptiste Daroussin /* selector */ 34561ba55bcSBaptiste Daroussin wmove(m->pad, y, m->xselector); 34661ba55bcSBaptiste Daroussin wattron(m->pad, focus ? t.menu.f_selectorcolor : t.menu.selectorcolor); 347bce40c02SAlfonso S. Siciliano if (pritem->type == CHECKLISTMODE) 34861ba55bcSBaptiste Daroussin wprintw(m->pad, "[%c]", pritem->on ? 'X' : ' '); 349bce40c02SAlfonso S. Siciliano if (pritem->type == RADIOLISTMODE) 35061ba55bcSBaptiste Daroussin wprintw(m->pad, "(%c)", pritem->on ? '*' : ' '); 35161ba55bcSBaptiste Daroussin wattroff(m->pad, focus ? t.menu.f_selectorcolor : t.menu.selectorcolor); 352c76f0793SBaptiste Daroussin 353c76f0793SBaptiste Daroussin /* name */ 354263660c0SAlfonso Siciliano colorname = focus ? t.menu.f_namecolor : t.menu.namecolor; 355263660c0SAlfonso Siciliano if (conf->menu.no_name == false) { 35661ba55bcSBaptiste Daroussin wattron(m->pad, colorname); 35761ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xname + pritem->depth, pritem->name); 35861ba55bcSBaptiste Daroussin wattroff(m->pad, colorname); 359c76f0793SBaptiste Daroussin } 360c76f0793SBaptiste Daroussin 361c76f0793SBaptiste Daroussin /* description */ 3628c4f4028SBaptiste Daroussin if (conf->menu.no_name) 363263660c0SAlfonso Siciliano colordesc = focus ? t.menu.f_namecolor : t.menu.namecolor; 3648c4f4028SBaptiste Daroussin else 365263660c0SAlfonso Siciliano colordesc = focus ? t.menu.f_desccolor : t.menu.desccolor; 366263660c0SAlfonso Siciliano 367263660c0SAlfonso Siciliano if (conf->menu.no_desc == false) { 36861ba55bcSBaptiste Daroussin wattron(m->pad, colordesc); 369f499134dSBaptiste Daroussin if (conf->menu.no_name) 37061ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xname + pritem->depth, 37161ba55bcSBaptiste Daroussin pritem->desc); 372c76f0793SBaptiste Daroussin else 37361ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xdesc, pritem->desc); 37461ba55bcSBaptiste Daroussin wattroff(m->pad, colordesc); 375c76f0793SBaptiste Daroussin } 376c76f0793SBaptiste Daroussin 3778c4f4028SBaptiste Daroussin /* shortcut */ 378263660c0SAlfonso Siciliano if (conf->menu.shortcut_buttons == false) { 379263660c0SAlfonso Siciliano colorshortcut = focus ? 380263660c0SAlfonso Siciliano t.menu.f_shortcutcolor : t.menu.shortcutcolor; 38161ba55bcSBaptiste Daroussin wattron(m->pad, colorshortcut); 38261ba55bcSBaptiste Daroussin mvwaddwch(m->pad, y, m->xname + pritem->depth, pritem->shortcut); 38361ba55bcSBaptiste Daroussin wattroff(m->pad, colorshortcut); 3848c4f4028SBaptiste Daroussin } 3858c4f4028SBaptiste Daroussin 3868c4f4028SBaptiste Daroussin /* bottom description */ 38761ba55bcSBaptiste Daroussin if (m->hasbottomdesc) { 388263660c0SAlfonso Siciliano move(SCREENLINES - 1, 2); 389c76f0793SBaptiste Daroussin clrtoeol(); 39061ba55bcSBaptiste Daroussin if (focus) { 391b319d934SAlfonso S. Siciliano attron(t.menu.bottomdesccolor); 39261ba55bcSBaptiste Daroussin addstr(pritem->bottomdesc); 393b319d934SAlfonso S. Siciliano attroff(t.menu.bottomdesccolor); 394c76f0793SBaptiste Daroussin refresh(); 395c76f0793SBaptiste Daroussin } 396c76f0793SBaptiste Daroussin } 39761ba55bcSBaptiste Daroussin } 398c76f0793SBaptiste Daroussin 39961ba55bcSBaptiste Daroussin static void update_menubox(struct bsddialog_conf *conf, struct privatemenu *m) 400b319d934SAlfonso S. Siciliano { 40161ba55bcSBaptiste Daroussin int h, w; 402b319d934SAlfonso S. Siciliano 40361ba55bcSBaptiste Daroussin draw_borders(conf, m->box, LOWERED); 40461ba55bcSBaptiste Daroussin getmaxyx(m->box, h, w); 40561ba55bcSBaptiste Daroussin 40661ba55bcSBaptiste Daroussin if (m->nitems > (int)m->menurows) { 40761ba55bcSBaptiste Daroussin wattron(m->box, t.dialog.arrowcolor); 40861ba55bcSBaptiste Daroussin if (m->ypad > 0) 409*a6d8be45SAlfonso S. Siciliano mvwhline(m->box, 0, 2, UARROW(conf), 3); 410b319d934SAlfonso S. Siciliano 41161ba55bcSBaptiste Daroussin if ((m->ypad + (int)m->menurows) < m->nitems) 412*a6d8be45SAlfonso S. Siciliano mvwhline(m->box, h-1, 2, DARROW(conf), 3); 413b319d934SAlfonso S. Siciliano 41461ba55bcSBaptiste Daroussin mvwprintw(m->box, h-1, w-6, "%3d%%", 41561ba55bcSBaptiste Daroussin 100 * (m->ypad + m->menurows) / m->nitems); 41661ba55bcSBaptiste Daroussin wattroff(m->box, t.dialog.arrowcolor); 417b319d934SAlfonso S. Siciliano } 418b319d934SAlfonso S. Siciliano } 419b319d934SAlfonso S. Siciliano 42061ba55bcSBaptiste Daroussin static int menu_size_position(struct dialog *d, struct privatemenu *m) 421c76f0793SBaptiste Daroussin { 42261ba55bcSBaptiste Daroussin int htext, hmenu; 423c76f0793SBaptiste Daroussin 42461ba55bcSBaptiste Daroussin if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0) 425263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 426c76f0793SBaptiste Daroussin 42761ba55bcSBaptiste Daroussin hmenu = (int)(m->menurows == BSDDIALOG_AUTOSIZE) ? 42861ba55bcSBaptiste Daroussin (int)m->nitems : (int)m->menurows; 42961ba55bcSBaptiste Daroussin hmenu += 2; /* menu borders */ 43061ba55bcSBaptiste Daroussin /* 43161ba55bcSBaptiste Daroussin * algo 1: notext = 1 (grows vertically). 43261ba55bcSBaptiste Daroussin * algo 2: notext = hmenu (grows horizontally, better for little term). 43361ba55bcSBaptiste Daroussin */ 43461ba55bcSBaptiste Daroussin if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w, 43561ba55bcSBaptiste Daroussin d->text, &htext, &d->bs, hmenu, m->line + 4) != 0) 43661ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 43761ba55bcSBaptiste Daroussin /* avoid menurows overflow and menurows becomes "at most menurows" */ 43861ba55bcSBaptiste Daroussin if (d->h - BORDERS - htext - HBUTTONS <= 2 /* menuborders */) 43961ba55bcSBaptiste Daroussin m->menurows = (m->nitems > 0) ? 1 : 0; /* widget_checksize() */ 440b319d934SAlfonso S. Siciliano else 44161ba55bcSBaptiste Daroussin m->menurows = MIN(d->h - BORDERS - htext - HBUTTONS, hmenu) - 2; 442263660c0SAlfonso Siciliano 44361ba55bcSBaptiste Daroussin /* 44461ba55bcSBaptiste Daroussin * no minw=linelen to avoid big menu fault, then some col can be 44561ba55bcSBaptiste Daroussin * hidden (example portconfig www/apache24). 44661ba55bcSBaptiste Daroussin */ 44761ba55bcSBaptiste Daroussin if (widget_checksize(d->h, d->w, &d->bs, 44861ba55bcSBaptiste Daroussin 2 /* border box */ + MIN(m->menurows, 1), 0) != 0) 44961ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 45061ba55bcSBaptiste Daroussin 45161ba55bcSBaptiste Daroussin if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0) 45261ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 45384823cc7SAlfonso S. Siciliano 454263660c0SAlfonso Siciliano return (0); 455c76f0793SBaptiste Daroussin } 456c76f0793SBaptiste Daroussin 45761ba55bcSBaptiste Daroussin static int mixedlist_redraw(struct dialog *d, struct privatemenu *m) 458c76f0793SBaptiste Daroussin { 45961ba55bcSBaptiste Daroussin if (d->built) { 46061ba55bcSBaptiste Daroussin hide_dialog(d); 46161ba55bcSBaptiste Daroussin refresh(); /* Important for decreasing screen */ 46261ba55bcSBaptiste Daroussin } 46361ba55bcSBaptiste Daroussin m->menurows = m->apimenurows; 46461ba55bcSBaptiste Daroussin if (menu_size_position(d, m) != 0) 46561ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 46661ba55bcSBaptiste Daroussin if (draw_dialog(d) != 0) 46761ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 46861ba55bcSBaptiste Daroussin if (d->built) 46961ba55bcSBaptiste Daroussin refresh(); /* Important to fix grey lines expanding screen */ 47061ba55bcSBaptiste Daroussin TEXTPAD(d, 2/*bmenu*/ + m->menurows + HBUTTONS); 471c76f0793SBaptiste Daroussin 47261ba55bcSBaptiste Daroussin /* selected item in view*/ 47361ba55bcSBaptiste Daroussin if (m->ypad > m->sel && m->ypad > 0) 47461ba55bcSBaptiste Daroussin m->ypad = m->sel; 47561ba55bcSBaptiste Daroussin if ((int)(m->ypad + m->menurows) <= m->sel) 47661ba55bcSBaptiste Daroussin m->ypad = m->sel - m->menurows + 1; 47761ba55bcSBaptiste Daroussin /* lower pad after a terminal expansion */ 47861ba55bcSBaptiste Daroussin if (m->ypad > 0 && (m->nitems - m->ypad) < (int)m->menurows) 47961ba55bcSBaptiste Daroussin m->ypad = m->nitems - m->menurows; 480c76f0793SBaptiste Daroussin 48161ba55bcSBaptiste Daroussin update_box(d->conf, m->box, d->y + d->h - 5 - m->menurows, d->x + 2, 48261ba55bcSBaptiste Daroussin m->menurows+2, d->w-4, LOWERED); 48361ba55bcSBaptiste Daroussin update_menubox(d->conf, m); 48461ba55bcSBaptiste Daroussin wnoutrefresh(m->box); 485c76f0793SBaptiste Daroussin 48661ba55bcSBaptiste Daroussin m->ys = d->y + d->h - 5 - m->menurows + 1; 48761ba55bcSBaptiste Daroussin m->ye = d->y + d->h - 5 ; 48861ba55bcSBaptiste Daroussin if (d->conf->menu.align_left || (int)m->line > d->w - 6) { 48961ba55bcSBaptiste Daroussin m->xs = d->x + 3; 49061ba55bcSBaptiste Daroussin m->xe = m->xs + d->w - 7; 49161ba55bcSBaptiste Daroussin } else { /* center */ 49261ba55bcSBaptiste Daroussin m->xs = d->x + 3 + (d->w-6)/2 - m->line/2; 49361ba55bcSBaptiste Daroussin m->xe = m->xs + d->w - 5; 49461ba55bcSBaptiste Daroussin } 49561ba55bcSBaptiste Daroussin drawseparators(d->conf, m); /* uses xe - xs */ 49661ba55bcSBaptiste Daroussin pnoutrefresh(m->pad, m->ypad, 0, m->ys, m->xs, m->ye, m->xe); 497c76f0793SBaptiste Daroussin 498263660c0SAlfonso Siciliano return (0); 499c76f0793SBaptiste Daroussin } 500c76f0793SBaptiste Daroussin 501c76f0793SBaptiste Daroussin static int 502263660c0SAlfonso Siciliano do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols, 503263660c0SAlfonso Siciliano unsigned int menurows, enum menumode mode, unsigned int ngroups, 504c76f0793SBaptiste Daroussin struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) 505c76f0793SBaptiste Daroussin { 50661ba55bcSBaptiste Daroussin bool loop, changeitem; 50761ba55bcSBaptiste Daroussin int i, next, retval; 508b319d934SAlfonso S. Siciliano wint_t input; 50961ba55bcSBaptiste Daroussin struct privatemenu m; 51061ba55bcSBaptiste Daroussin struct dialog d; 511c76f0793SBaptiste Daroussin 51261ba55bcSBaptiste Daroussin if (prepare_dialog(conf, text, rows, cols, &d) != 0) 513263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 51461ba55bcSBaptiste Daroussin set_buttons(&d, conf->menu.shortcut_buttons, OK_LABEL, CANCEL_LABEL); 51561ba55bcSBaptiste Daroussin if (d.conf->menu.no_name && d.conf->menu.no_desc) 51661ba55bcSBaptiste Daroussin RETURN_ERROR("Both conf.menu.no_name and conf.menu.no_desc"); 51761ba55bcSBaptiste Daroussin 51861ba55bcSBaptiste Daroussin if (build_privatemenu(conf, &m, mode, ngroups, groups) != 0) 519263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 520c76f0793SBaptiste Daroussin 52161ba55bcSBaptiste Daroussin if ((m.box = newwin(1, 1, 1, 1)) == NULL) 52261ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot build WINDOW box menu"); 52361ba55bcSBaptiste Daroussin wbkgd(m.box, t.dialog.color); 52461ba55bcSBaptiste Daroussin m.pad = newpad(m.nitems, m.line); 52561ba55bcSBaptiste Daroussin wbkgd(m.pad, t.dialog.color); 526c76f0793SBaptiste Daroussin 52761ba55bcSBaptiste Daroussin for (i = 0; i < m.nitems; i++) 52861ba55bcSBaptiste Daroussin drawitem(conf, &m, i, false); 52961ba55bcSBaptiste Daroussin m.sel = getfirst_with_default(m.nitems, m.pritems, ngroups, groups, 530263660c0SAlfonso Siciliano focuslist, focusitem); 53161ba55bcSBaptiste Daroussin if (m.sel >= 0) 53261ba55bcSBaptiste Daroussin drawitem(d.conf, &m, m.sel, true); 53361ba55bcSBaptiste Daroussin m.ypad = 0; 53461ba55bcSBaptiste Daroussin m.apimenurows = menurows; 53561ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 53661ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 537c76f0793SBaptiste Daroussin 53861ba55bcSBaptiste Daroussin changeitem = false; 539c76f0793SBaptiste Daroussin loop = true; 540c76f0793SBaptiste Daroussin while (loop) { 54161ba55bcSBaptiste Daroussin doupdate(); 542b319d934SAlfonso S. Siciliano if (get_wch(&input) == ERR) 543b319d934SAlfonso S. Siciliano continue; 544c76f0793SBaptiste Daroussin switch(input) { 545c76f0793SBaptiste Daroussin case KEY_ENTER: 546c76f0793SBaptiste Daroussin case 10: /* Enter */ 54761ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 54861ba55bcSBaptiste Daroussin if (m.sel >= 0 && m.pritems[m.sel].type == MENUMODE) 54961ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 550c76f0793SBaptiste Daroussin loop = false; 551c76f0793SBaptiste Daroussin break; 552c76f0793SBaptiste Daroussin case 27: /* Esc */ 553263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 554b319d934SAlfonso S. Siciliano retval = BSDDIALOG_ESC; 55561ba55bcSBaptiste Daroussin if (m.sel >= 0 && 55661ba55bcSBaptiste Daroussin m.pritems[m.sel].type == MENUMODE) 55761ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 558c76f0793SBaptiste Daroussin loop = false; 559263660c0SAlfonso Siciliano } 560c76f0793SBaptiste Daroussin break; 561c76f0793SBaptiste Daroussin case '\t': /* TAB */ 56261ba55bcSBaptiste Daroussin case KEY_RIGHT: 56361ba55bcSBaptiste Daroussin d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons; 56461ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 565c76f0793SBaptiste Daroussin break; 566c76f0793SBaptiste Daroussin case KEY_LEFT: 56761ba55bcSBaptiste Daroussin d.bs.curr--; 56861ba55bcSBaptiste Daroussin if (d.bs.curr < 0) 56961ba55bcSBaptiste Daroussin d.bs.curr = d.bs.nbuttons - 1; 57061ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 571c76f0793SBaptiste Daroussin break; 572c76f0793SBaptiste Daroussin case KEY_F(1): 573bce40c02SAlfonso S. Siciliano if (conf->key.f1_file == NULL && 574bce40c02SAlfonso S. Siciliano conf->key.f1_message == NULL) 575c76f0793SBaptiste Daroussin break; 57661ba55bcSBaptiste Daroussin if (f1help_dialog(conf) != 0) 577263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 57861ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 57961ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 58061ba55bcSBaptiste Daroussin break; 581*a6d8be45SAlfonso S. Siciliano case KEY_CTRL('l'): 582c76f0793SBaptiste Daroussin case KEY_RESIZE: 58361ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 584263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 585c76f0793SBaptiste Daroussin break; 586c76f0793SBaptiste Daroussin } 587c76f0793SBaptiste Daroussin 58861ba55bcSBaptiste Daroussin if (m.sel < 0) 589c76f0793SBaptiste Daroussin continue; 590c76f0793SBaptiste Daroussin switch(input) { 591c76f0793SBaptiste Daroussin case KEY_HOME: 59261ba55bcSBaptiste Daroussin next = getnext(m.nitems, m.pritems, -1); 59361ba55bcSBaptiste Daroussin changeitem = next != m.sel; 594c76f0793SBaptiste Daroussin break; 595*a6d8be45SAlfonso S. Siciliano case '-': 596*a6d8be45SAlfonso S. Siciliano case KEY_CTRL('p'): 597263660c0SAlfonso Siciliano case KEY_UP: 59861ba55bcSBaptiste Daroussin next = getprev(m.pritems, m.sel); 59961ba55bcSBaptiste Daroussin changeitem = next != m.sel; 600263660c0SAlfonso Siciliano break; 601263660c0SAlfonso Siciliano case KEY_PPAGE: 60261ba55bcSBaptiste Daroussin next = getfastprev(m.menurows, m.pritems, m.sel); 60361ba55bcSBaptiste Daroussin changeitem = next != m.sel; 604c76f0793SBaptiste Daroussin break; 605c76f0793SBaptiste Daroussin case KEY_END: 60661ba55bcSBaptiste Daroussin next = getprev(m.pritems, m.nitems); 60761ba55bcSBaptiste Daroussin changeitem = next != m.sel; 608263660c0SAlfonso Siciliano break; 609*a6d8be45SAlfonso S. Siciliano case '+': 610*a6d8be45SAlfonso S. Siciliano case KEY_CTRL('n'): 611c76f0793SBaptiste Daroussin case KEY_DOWN: 61261ba55bcSBaptiste Daroussin next = getnext(m.nitems, m.pritems, m.sel); 61361ba55bcSBaptiste Daroussin changeitem = next != m.sel; 614263660c0SAlfonso Siciliano break; 615c76f0793SBaptiste Daroussin case KEY_NPAGE: 61661ba55bcSBaptiste Daroussin next = getfastnext(m.menurows, m.nitems, m.pritems, m.sel); 61761ba55bcSBaptiste Daroussin changeitem = next != m.sel; 618c76f0793SBaptiste Daroussin break; 619c76f0793SBaptiste Daroussin case ' ': /* Space */ 62061ba55bcSBaptiste Daroussin if (m.pritems[m.sel].type == MENUMODE) { 62161ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 62261ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 62384823cc7SAlfonso S. Siciliano loop = false; 62461ba55bcSBaptiste Daroussin } else if (m.pritems[m.sel].type == CHECKLISTMODE) { 62561ba55bcSBaptiste Daroussin m.pritems[m.sel].on = !m.pritems[m.sel].on; 62684823cc7SAlfonso S. Siciliano } else { /* RADIOLISTMODE */ 62761ba55bcSBaptiste Daroussin for (i = m.sel - m.pritems[m.sel].index; 62861ba55bcSBaptiste Daroussin i < m.nitems && 62961ba55bcSBaptiste Daroussin m.pritems[i].group == m.pritems[m.sel].group; 630263660c0SAlfonso Siciliano i++) { 63161ba55bcSBaptiste Daroussin if (i != m.sel && m.pritems[i].on) { 63261ba55bcSBaptiste Daroussin m.pritems[i].on = false; 63361ba55bcSBaptiste Daroussin drawitem(conf, &m, i, false); 634c76f0793SBaptiste Daroussin } 635c76f0793SBaptiste Daroussin } 63661ba55bcSBaptiste Daroussin m.pritems[m.sel].on = !m.pritems[m.sel].on; 637263660c0SAlfonso Siciliano } 63861ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, true); 63961ba55bcSBaptiste Daroussin pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe); 640263660c0SAlfonso Siciliano break; 6418c4f4028SBaptiste Daroussin default: 64261ba55bcSBaptiste Daroussin if (conf->menu.shortcut_buttons) { 64361ba55bcSBaptiste Daroussin if (shortcut_buttons(input, &d.bs)) { 64461ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 64561ba55bcSBaptiste Daroussin doupdate(); 64661ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 64761ba55bcSBaptiste Daroussin if (m.pritems[m.sel].type == MENUMODE) 64861ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 6498c4f4028SBaptiste Daroussin loop = false; 6508c4f4028SBaptiste Daroussin } 6518c4f4028SBaptiste Daroussin break; 6528c4f4028SBaptiste Daroussin } 6538c4f4028SBaptiste Daroussin 654263660c0SAlfonso Siciliano /* shourtcut items */ 65561ba55bcSBaptiste Daroussin next = getnextshortcut(m.nitems, m.pritems, m.sel, 656263660c0SAlfonso Siciliano input); 65761ba55bcSBaptiste Daroussin changeitem = next != m.sel; 65861ba55bcSBaptiste Daroussin } /* end switch get_wch() */ 659263660c0SAlfonso Siciliano 66061ba55bcSBaptiste Daroussin if (changeitem) { 66161ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, false); 66261ba55bcSBaptiste Daroussin m.sel = next; 66361ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, true); 66461ba55bcSBaptiste Daroussin if (m.ypad > m.sel && m.ypad > 0) 66561ba55bcSBaptiste Daroussin m.ypad = m.sel; 66661ba55bcSBaptiste Daroussin if ((int)(m.ypad + m.menurows) <= m.sel) 66761ba55bcSBaptiste Daroussin m.ypad = m.sel - m.menurows + 1; 66861ba55bcSBaptiste Daroussin update_menubox(conf, &m); 66961ba55bcSBaptiste Daroussin wnoutrefresh(m.box); 67061ba55bcSBaptiste Daroussin pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe); 67161ba55bcSBaptiste Daroussin changeitem = false; 672c76f0793SBaptiste Daroussin } 67361ba55bcSBaptiste Daroussin } /* end while (loop) */ 67461ba55bcSBaptiste Daroussin 67561ba55bcSBaptiste Daroussin set_return_on(&m, groups); 676c76f0793SBaptiste Daroussin 677c76f0793SBaptiste Daroussin if (focuslist != NULL) 67861ba55bcSBaptiste Daroussin *focuslist = m.sel < 0 ? -1 : m.pritems[m.sel].group; 679c76f0793SBaptiste Daroussin if (focusitem !=NULL) 68061ba55bcSBaptiste Daroussin *focusitem = m.sel < 0 ? -1 : m.pritems[m.sel].index; 681c76f0793SBaptiste Daroussin 68261ba55bcSBaptiste Daroussin if (m.hasbottomdesc && conf->clear) { 68361ba55bcSBaptiste Daroussin move(SCREENLINES - 1, 2); 68461ba55bcSBaptiste Daroussin clrtoeol(); 68561ba55bcSBaptiste Daroussin } 68661ba55bcSBaptiste Daroussin delwin(m.pad); 68761ba55bcSBaptiste Daroussin delwin(m.box); 68861ba55bcSBaptiste Daroussin end_dialog(&d); 68961ba55bcSBaptiste Daroussin free(m.pritems); 690c76f0793SBaptiste Daroussin 691b319d934SAlfonso S. Siciliano return (retval); 692c76f0793SBaptiste Daroussin } 693c76f0793SBaptiste Daroussin 694263660c0SAlfonso Siciliano /* API */ 695263660c0SAlfonso Siciliano int 696263660c0SAlfonso Siciliano bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, 697263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int ngroups, 698263660c0SAlfonso Siciliano struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) 699c76f0793SBaptiste Daroussin { 700b319d934SAlfonso S. Siciliano int retval; 701c76f0793SBaptiste Daroussin 702b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE, 703c76f0793SBaptiste Daroussin ngroups, groups, focuslist, focusitem); 704c76f0793SBaptiste Daroussin 705b319d934SAlfonso S. Siciliano return (retval); 706c76f0793SBaptiste Daroussin } 707c76f0793SBaptiste Daroussin 708c76f0793SBaptiste Daroussin int 709263660c0SAlfonso Siciliano bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows, 710263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 711263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 712c76f0793SBaptiste Daroussin { 713b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 714c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 71561ba55bcSBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items, 0}; 716c76f0793SBaptiste Daroussin 71761ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 718b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE, 719263660c0SAlfonso Siciliano 1, &group, &focuslist, focusitem); 720c76f0793SBaptiste Daroussin 721b319d934SAlfonso S. Siciliano return (retval); 722c76f0793SBaptiste Daroussin } 723c76f0793SBaptiste Daroussin 724c76f0793SBaptiste Daroussin int 725263660c0SAlfonso Siciliano bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows, 726263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 727263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 728c76f0793SBaptiste Daroussin { 729b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 730c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 73161ba55bcSBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items, 0}; 732c76f0793SBaptiste Daroussin 73361ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 734b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1, 735263660c0SAlfonso Siciliano &group, &focuslist, focusitem); 736c76f0793SBaptiste Daroussin 737b319d934SAlfonso S. Siciliano return (retval); 738c76f0793SBaptiste Daroussin } 739c76f0793SBaptiste Daroussin 740c76f0793SBaptiste Daroussin int 741263660c0SAlfonso Siciliano bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows, 742263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 743263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 744c76f0793SBaptiste Daroussin { 745b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 746c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 74761ba55bcSBaptiste Daroussin BSDDIALOG_RADIOLIST /* unused */, nitems, items, 0}; 748c76f0793SBaptiste Daroussin 74961ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 750b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE, 751263660c0SAlfonso Siciliano 1, &group, &focuslist, focusitem); 752c76f0793SBaptiste Daroussin 753b319d934SAlfonso S. Siciliano return (retval); 754c76f0793SBaptiste Daroussin } 755