1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4*61ba55bcSBaptiste Daroussin * Copyright (c) 2021-2023 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 { 44*61ba55bcSBaptiste Daroussin const char *prefix; 45*61ba55bcSBaptiste Daroussin bool on; /* menu changes, not API on */ 46*61ba55bcSBaptiste Daroussin unsigned int depth; 47*61ba55bcSBaptiste Daroussin const char *name; 48*61ba55bcSBaptiste Daroussin const char *desc; 49*61ba55bcSBaptiste Daroussin const char *bottomdesc; 50*61ba55bcSBaptiste Daroussin int group; /* index menu in menugroup */ 51*61ba55bcSBaptiste Daroussin int index; /* real item index inside its menu */ 52263660c0SAlfonso Siciliano enum menumode type; 53*61ba55bcSBaptiste Daroussin wchar_t shortcut; 54263660c0SAlfonso Siciliano }; 55c76f0793SBaptiste Daroussin 56*61ba55bcSBaptiste Daroussin struct privatemenu { 57*61ba55bcSBaptiste Daroussin WINDOW *box; /* only for borders */ 58*61ba55bcSBaptiste Daroussin WINDOW *pad; /* pad for the private items */ 59*61ba55bcSBaptiste Daroussin int ypad; /* start pad line */ 60*61ba55bcSBaptiste Daroussin int ys, ye, xs, xe; /* pad pos */ 61*61ba55bcSBaptiste Daroussin unsigned int xselector; /* [] */ 62*61ba55bcSBaptiste Daroussin unsigned int xname; /* real x: xname + item.depth */ 63*61ba55bcSBaptiste Daroussin unsigned int xdesc; /* real x: xdesc + item.depth */ 64*61ba55bcSBaptiste Daroussin unsigned int line; /* wpad: prefix [] depth name desc */ 65*61ba55bcSBaptiste Daroussin unsigned int apimenurows; 66*61ba55bcSBaptiste Daroussin unsigned int menurows; /* real menurows after menu_size_position() */ 67*61ba55bcSBaptiste Daroussin int nitems; /* total nitems (all groups * all items) */ 68*61ba55bcSBaptiste Daroussin struct privateitem *pritems; 69*61ba55bcSBaptiste Daroussin int sel; /* current focus item, can be -1 */ 70*61ba55bcSBaptiste Daroussin bool hasbottomdesc; 71*61ba55bcSBaptiste Daroussin }; 72*61ba55bcSBaptiste Daroussin 73*61ba55bcSBaptiste Daroussin static enum menumode 74*61ba55bcSBaptiste Daroussin getmode(enum menumode mode, struct bsddialog_menugroup group) 75263660c0SAlfonso Siciliano { 76*61ba55bcSBaptiste Daroussin if (mode == MIXEDLISTMODE) { 77*61ba55bcSBaptiste Daroussin if (group.type == BSDDIALOG_SEPARATOR) 78*61ba55bcSBaptiste Daroussin mode = SEPARATORMODE; 79*61ba55bcSBaptiste Daroussin else if (group.type == BSDDIALOG_RADIOLIST) 80*61ba55bcSBaptiste Daroussin mode = RADIOLISTMODE; 81*61ba55bcSBaptiste Daroussin else if (group.type == BSDDIALOG_CHECKLIST) 82*61ba55bcSBaptiste Daroussin mode = CHECKLISTMODE; 83*61ba55bcSBaptiste Daroussin } 84*61ba55bcSBaptiste Daroussin 85*61ba55bcSBaptiste Daroussin return (mode); 86*61ba55bcSBaptiste Daroussin } 87*61ba55bcSBaptiste Daroussin 88*61ba55bcSBaptiste Daroussin static int 89*61ba55bcSBaptiste Daroussin build_privatemenu(struct bsddialog_conf *conf, struct privatemenu *m, 90*61ba55bcSBaptiste Daroussin enum menumode mode, unsigned int ngroups, 91*61ba55bcSBaptiste Daroussin struct bsddialog_menugroup *groups) 92*61ba55bcSBaptiste Daroussin { 93*61ba55bcSBaptiste Daroussin bool onetrue; 94263660c0SAlfonso Siciliano int i, j, abs; 95*61ba55bcSBaptiste Daroussin unsigned int maxsepstr, maxprefix, selectorlen, maxdepth; 96*61ba55bcSBaptiste Daroussin unsigned int maxname, maxdesc; 97*61ba55bcSBaptiste Daroussin struct bsddialog_menuitem *item; 98*61ba55bcSBaptiste Daroussin struct privateitem *pritem; 99263660c0SAlfonso Siciliano 100*61ba55bcSBaptiste Daroussin /* nitems and fault checks */ 101*61ba55bcSBaptiste Daroussin CHECK_ARRAY(ngroups, groups); 102*61ba55bcSBaptiste Daroussin m->nitems = 0; 103*61ba55bcSBaptiste Daroussin for (i = 0; i < (int)ngroups; i++) { 104*61ba55bcSBaptiste Daroussin CHECK_ARRAY(groups[i].nitems, groups[i].items); 105*61ba55bcSBaptiste Daroussin m->nitems += (int)groups[i].nitems; 106*61ba55bcSBaptiste Daroussin } 107c76f0793SBaptiste Daroussin 108*61ba55bcSBaptiste Daroussin /* alloc and set private items */ 109*61ba55bcSBaptiste Daroussin m->pritems = calloc(m->nitems, sizeof (struct privateitem)); 110*61ba55bcSBaptiste Daroussin if (m->pritems == NULL) 111*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot allocate memory for internal menu items"); 112*61ba55bcSBaptiste Daroussin m->hasbottomdesc = false; 113*61ba55bcSBaptiste Daroussin abs = 0; 114*61ba55bcSBaptiste Daroussin for (i = 0; i < (int)ngroups; i++) { 115*61ba55bcSBaptiste Daroussin onetrue = false; 116*61ba55bcSBaptiste Daroussin for (j = 0; j < (int)groups[i].nitems; j++) { 117*61ba55bcSBaptiste Daroussin item = &groups[i].items[j]; 118*61ba55bcSBaptiste Daroussin pritem = &m->pritems[abs]; 119*61ba55bcSBaptiste Daroussin 120*61ba55bcSBaptiste Daroussin if (getmode(mode, groups[i]) == MENUMODE) { 121*61ba55bcSBaptiste Daroussin m->pritems[abs].on = false; 122*61ba55bcSBaptiste Daroussin } else if (getmode(mode, groups[i]) == RADIOLISTMODE) { 123*61ba55bcSBaptiste Daroussin m->pritems[abs].on = onetrue ? false : item->on; 124*61ba55bcSBaptiste Daroussin if (m->pritems[abs].on) 125*61ba55bcSBaptiste Daroussin onetrue = true; 126*61ba55bcSBaptiste Daroussin } else { /* CHECKLISTMODE */ 127*61ba55bcSBaptiste Daroussin m->pritems[abs].on = item->on; 128*61ba55bcSBaptiste Daroussin } 129*61ba55bcSBaptiste Daroussin pritem->group = i; 130*61ba55bcSBaptiste Daroussin pritem->index = j; 131*61ba55bcSBaptiste Daroussin pritem->type = getmode(mode, groups[i]); 132*61ba55bcSBaptiste Daroussin 133*61ba55bcSBaptiste Daroussin pritem->prefix = CHECK_STR(item->prefix); 134*61ba55bcSBaptiste Daroussin pritem->depth = item->depth; 135*61ba55bcSBaptiste Daroussin pritem->name = CHECK_STR(item->name); 136*61ba55bcSBaptiste Daroussin pritem->desc = CHECK_STR(item->desc); 137*61ba55bcSBaptiste Daroussin pritem->bottomdesc = CHECK_STR(item->bottomdesc); 138*61ba55bcSBaptiste Daroussin if (item->bottomdesc != NULL) 139*61ba55bcSBaptiste Daroussin m->hasbottomdesc = true; 140*61ba55bcSBaptiste Daroussin 141*61ba55bcSBaptiste Daroussin mbtowc(&pritem->shortcut, conf->menu.no_name ? 142*61ba55bcSBaptiste Daroussin pritem->desc : pritem->name, MB_CUR_MAX); 143*61ba55bcSBaptiste Daroussin 144*61ba55bcSBaptiste Daroussin abs++; 145*61ba55bcSBaptiste Daroussin } 146*61ba55bcSBaptiste Daroussin } 147*61ba55bcSBaptiste Daroussin 148*61ba55bcSBaptiste Daroussin /* positions */ 149*61ba55bcSBaptiste Daroussin m->xselector = m->xname = m->xdesc = m->line = 0; 150*61ba55bcSBaptiste Daroussin maxsepstr = maxprefix = selectorlen = maxdepth = maxname = maxdesc = 0; 151*61ba55bcSBaptiste Daroussin for (i = 0; i < m->nitems; i++) { 152*61ba55bcSBaptiste Daroussin if (m->pritems[i].type == RADIOLISTMODE || 153*61ba55bcSBaptiste Daroussin m->pritems[i].type == CHECKLISTMODE) 154*61ba55bcSBaptiste Daroussin selectorlen = 4; 155*61ba55bcSBaptiste Daroussin 156*61ba55bcSBaptiste Daroussin if (m->pritems[i].type == SEPARATORMODE) { 157*61ba55bcSBaptiste Daroussin maxsepstr = MAX(maxsepstr, 158*61ba55bcSBaptiste Daroussin strcols(m->pritems[i].name) + 159*61ba55bcSBaptiste Daroussin strcols(m->pritems[i].desc)); 160c76f0793SBaptiste Daroussin continue; 161c76f0793SBaptiste Daroussin } 162263660c0SAlfonso Siciliano 163*61ba55bcSBaptiste Daroussin maxprefix = MAX(maxprefix, strcols(m->pritems[i].prefix)); 164*61ba55bcSBaptiste Daroussin maxdepth = MAX(maxdepth, m->pritems[i].depth); 165*61ba55bcSBaptiste Daroussin maxname = MAX(maxname, strcols(m->pritems[i].name)); 166*61ba55bcSBaptiste Daroussin maxdesc = MAX(maxdesc, strcols(m->pritems[i].desc)); 167c76f0793SBaptiste Daroussin } 168*61ba55bcSBaptiste Daroussin maxname = conf->menu.no_name ? 0 : maxname; 169*61ba55bcSBaptiste Daroussin maxdesc = conf->menu.no_desc ? 0 : maxdesc; 170*61ba55bcSBaptiste Daroussin 171*61ba55bcSBaptiste Daroussin m->xselector = maxprefix + (maxprefix != 0 ? 1 : 0); 172*61ba55bcSBaptiste Daroussin m->xname = m->xselector + selectorlen; 173*61ba55bcSBaptiste Daroussin m->xdesc = maxdepth + m->xname + maxname; 174*61ba55bcSBaptiste Daroussin m->xdesc += (maxname != 0 ? 1 : 0); 175*61ba55bcSBaptiste Daroussin m->line = MAX(maxsepstr + 3, m->xdesc + maxdesc); 176*61ba55bcSBaptiste Daroussin 177*61ba55bcSBaptiste Daroussin return (0); 178*61ba55bcSBaptiste Daroussin } 179*61ba55bcSBaptiste Daroussin 180*61ba55bcSBaptiste Daroussin static void 181*61ba55bcSBaptiste Daroussin set_return_on(struct privatemenu *m, struct bsddialog_menugroup *groups) 182*61ba55bcSBaptiste Daroussin { 183*61ba55bcSBaptiste Daroussin int i; 184*61ba55bcSBaptiste Daroussin struct privateitem *pritem; 185*61ba55bcSBaptiste Daroussin 186*61ba55bcSBaptiste Daroussin for(i = 0; i < m->nitems; i++) { 187*61ba55bcSBaptiste Daroussin if (m->pritems[i].type == SEPARATORMODE) 188*61ba55bcSBaptiste Daroussin continue; 189*61ba55bcSBaptiste Daroussin pritem = &m->pritems[i]; 190*61ba55bcSBaptiste 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 280*61ba55bcSBaptiste 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; 288*61ba55bcSBaptiste 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 299*61ba55bcSBaptiste Daroussin static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m) 300c76f0793SBaptiste Daroussin { 301*61ba55bcSBaptiste Daroussin int i, linech, realw, labellen; 302bce40c02SAlfonso S. Siciliano const char *desc, *name; 303263660c0SAlfonso Siciliano 304*61ba55bcSBaptiste Daroussin for (i = 0; i < m->nitems; i++) { 305*61ba55bcSBaptiste Daroussin if (m->pritems[i].type != SEPARATORMODE) 306bce40c02SAlfonso S. Siciliano continue; 307f499134dSBaptiste Daroussin if (conf->no_lines == false) { 308*61ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.desccolor); 309f499134dSBaptiste Daroussin linech = conf->ascii_lines ? '-' : ACS_HLINE; 310*61ba55bcSBaptiste Daroussin mvwhline(m->pad, i, 0, linech, m->line); 311*61ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.desccolor); 312c76f0793SBaptiste Daroussin } 313*61ba55bcSBaptiste Daroussin name = m->pritems[i].name; 314*61ba55bcSBaptiste Daroussin desc = m->pritems[i].desc; 315*61ba55bcSBaptiste Daroussin realw = m->xe - m->xs; 316b319d934SAlfonso S. Siciliano labellen = strcols(name) + strcols(desc) + 1; 317*61ba55bcSBaptiste Daroussin wmove(m->pad, i, (labellen < realw) ? realw/2 - labellen/2 : 0); 318*61ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.sepnamecolor); 319*61ba55bcSBaptiste Daroussin waddstr(m->pad, name); 320*61ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.sepnamecolor); 321b319d934SAlfonso S. Siciliano if (strcols(name) > 0 && strcols(desc) > 0) 322*61ba55bcSBaptiste Daroussin waddch(m->pad, ' '); 323*61ba55bcSBaptiste Daroussin wattron(m->pad, t.menu.sepdesccolor); 324*61ba55bcSBaptiste Daroussin waddstr(m->pad, desc); 325*61ba55bcSBaptiste Daroussin wattroff(m->pad, t.menu.sepdesccolor); 326bce40c02SAlfonso S. Siciliano } 327c76f0793SBaptiste Daroussin } 328c76f0793SBaptiste Daroussin 329bce40c02SAlfonso S. Siciliano static void 330*61ba55bcSBaptiste Daroussin drawitem(struct bsddialog_conf *conf, struct privatemenu *m, int y, bool focus) 331bce40c02SAlfonso S. Siciliano { 332bce40c02SAlfonso S. Siciliano int colordesc, colorname, colorshortcut; 333*61ba55bcSBaptiste Daroussin struct privateitem *pritem; 334bce40c02SAlfonso S. Siciliano 335*61ba55bcSBaptiste Daroussin pritem = &m->pritems[y]; 336bce40c02SAlfonso S. Siciliano 337c76f0793SBaptiste Daroussin /* prefix */ 338*61ba55bcSBaptiste Daroussin wattron(m->pad, focus ? t.menu.f_prefixcolor : t.menu.prefixcolor); 339*61ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, 0, pritem->prefix); 340*61ba55bcSBaptiste Daroussin wattroff(m->pad, focus ? t.menu.f_prefixcolor : t.menu.prefixcolor); 341c76f0793SBaptiste Daroussin 342c76f0793SBaptiste Daroussin /* selector */ 343*61ba55bcSBaptiste Daroussin wmove(m->pad, y, m->xselector); 344*61ba55bcSBaptiste Daroussin wattron(m->pad, focus ? t.menu.f_selectorcolor : t.menu.selectorcolor); 345bce40c02SAlfonso S. Siciliano if (pritem->type == CHECKLISTMODE) 346*61ba55bcSBaptiste Daroussin wprintw(m->pad, "[%c]", pritem->on ? 'X' : ' '); 347bce40c02SAlfonso S. Siciliano if (pritem->type == RADIOLISTMODE) 348*61ba55bcSBaptiste Daroussin wprintw(m->pad, "(%c)", pritem->on ? '*' : ' '); 349*61ba55bcSBaptiste Daroussin wattroff(m->pad, focus ? t.menu.f_selectorcolor : t.menu.selectorcolor); 350c76f0793SBaptiste Daroussin 351c76f0793SBaptiste Daroussin /* name */ 352263660c0SAlfonso Siciliano colorname = focus ? t.menu.f_namecolor : t.menu.namecolor; 353263660c0SAlfonso Siciliano if (conf->menu.no_name == false) { 354*61ba55bcSBaptiste Daroussin wattron(m->pad, colorname); 355*61ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xname + pritem->depth, pritem->name); 356*61ba55bcSBaptiste Daroussin wattroff(m->pad, colorname); 357c76f0793SBaptiste Daroussin } 358c76f0793SBaptiste Daroussin 359c76f0793SBaptiste Daroussin /* description */ 3608c4f4028SBaptiste Daroussin if (conf->menu.no_name) 361263660c0SAlfonso Siciliano colordesc = focus ? t.menu.f_namecolor : t.menu.namecolor; 3628c4f4028SBaptiste Daroussin else 363263660c0SAlfonso Siciliano colordesc = focus ? t.menu.f_desccolor : t.menu.desccolor; 364263660c0SAlfonso Siciliano 365263660c0SAlfonso Siciliano if (conf->menu.no_desc == false) { 366*61ba55bcSBaptiste Daroussin wattron(m->pad, colordesc); 367f499134dSBaptiste Daroussin if (conf->menu.no_name) 368*61ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xname + pritem->depth, 369*61ba55bcSBaptiste Daroussin pritem->desc); 370c76f0793SBaptiste Daroussin else 371*61ba55bcSBaptiste Daroussin mvwaddstr(m->pad, y, m->xdesc, pritem->desc); 372*61ba55bcSBaptiste Daroussin wattroff(m->pad, colordesc); 373c76f0793SBaptiste Daroussin } 374c76f0793SBaptiste Daroussin 3758c4f4028SBaptiste Daroussin /* shortcut */ 376263660c0SAlfonso Siciliano if (conf->menu.shortcut_buttons == false) { 377263660c0SAlfonso Siciliano colorshortcut = focus ? 378263660c0SAlfonso Siciliano t.menu.f_shortcutcolor : t.menu.shortcutcolor; 379*61ba55bcSBaptiste Daroussin wattron(m->pad, colorshortcut); 380*61ba55bcSBaptiste Daroussin mvwaddwch(m->pad, y, m->xname + pritem->depth, pritem->shortcut); 381*61ba55bcSBaptiste Daroussin wattroff(m->pad, colorshortcut); 3828c4f4028SBaptiste Daroussin } 3838c4f4028SBaptiste Daroussin 3848c4f4028SBaptiste Daroussin /* bottom description */ 385*61ba55bcSBaptiste Daroussin if (m->hasbottomdesc) { 386263660c0SAlfonso Siciliano move(SCREENLINES - 1, 2); 387c76f0793SBaptiste Daroussin clrtoeol(); 388*61ba55bcSBaptiste Daroussin if (focus) { 389b319d934SAlfonso S. Siciliano attron(t.menu.bottomdesccolor); 390*61ba55bcSBaptiste Daroussin addstr(pritem->bottomdesc); 391b319d934SAlfonso S. Siciliano attroff(t.menu.bottomdesccolor); 392c76f0793SBaptiste Daroussin refresh(); 393c76f0793SBaptiste Daroussin } 394c76f0793SBaptiste Daroussin } 395*61ba55bcSBaptiste Daroussin } 396c76f0793SBaptiste Daroussin 397*61ba55bcSBaptiste Daroussin static void update_menubox(struct bsddialog_conf *conf, struct privatemenu *m) 398b319d934SAlfonso S. Siciliano { 399*61ba55bcSBaptiste Daroussin int h, w; 400b319d934SAlfonso S. Siciliano 401*61ba55bcSBaptiste Daroussin draw_borders(conf, m->box, LOWERED); 402*61ba55bcSBaptiste Daroussin getmaxyx(m->box, h, w); 403*61ba55bcSBaptiste Daroussin 404*61ba55bcSBaptiste Daroussin if (m->nitems > (int)m->menurows) { 405*61ba55bcSBaptiste Daroussin wattron(m->box, t.dialog.arrowcolor); 406*61ba55bcSBaptiste Daroussin if (m->ypad > 0) 407*61ba55bcSBaptiste Daroussin mvwhline(m->box, 0, 2, 408b319d934SAlfonso S. Siciliano conf->ascii_lines ? '^' : ACS_UARROW, 3); 409b319d934SAlfonso S. Siciliano 410*61ba55bcSBaptiste Daroussin if ((m->ypad + (int)m->menurows) < m->nitems) 411*61ba55bcSBaptiste Daroussin mvwhline(m->box, h-1, 2, 412b319d934SAlfonso S. Siciliano conf->ascii_lines ? 'v' : ACS_DARROW, 3); 413b319d934SAlfonso S. Siciliano 414*61ba55bcSBaptiste Daroussin mvwprintw(m->box, h-1, w-6, "%3d%%", 415*61ba55bcSBaptiste Daroussin 100 * (m->ypad + m->menurows) / m->nitems); 416*61ba55bcSBaptiste Daroussin wattroff(m->box, t.dialog.arrowcolor); 417b319d934SAlfonso S. Siciliano } 418b319d934SAlfonso S. Siciliano } 419b319d934SAlfonso S. Siciliano 420*61ba55bcSBaptiste Daroussin static int menu_size_position(struct dialog *d, struct privatemenu *m) 421c76f0793SBaptiste Daroussin { 422*61ba55bcSBaptiste Daroussin int htext, hmenu; 423c76f0793SBaptiste Daroussin 424*61ba55bcSBaptiste Daroussin if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0) 425263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 426c76f0793SBaptiste Daroussin 427*61ba55bcSBaptiste Daroussin hmenu = (int)(m->menurows == BSDDIALOG_AUTOSIZE) ? 428*61ba55bcSBaptiste Daroussin (int)m->nitems : (int)m->menurows; 429*61ba55bcSBaptiste Daroussin hmenu += 2; /* menu borders */ 430*61ba55bcSBaptiste Daroussin /* 431*61ba55bcSBaptiste Daroussin * algo 1: notext = 1 (grows vertically). 432*61ba55bcSBaptiste Daroussin * algo 2: notext = hmenu (grows horizontally, better for little term). 433*61ba55bcSBaptiste Daroussin */ 434*61ba55bcSBaptiste Daroussin if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w, 435*61ba55bcSBaptiste Daroussin d->text, &htext, &d->bs, hmenu, m->line + 4) != 0) 436*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 437*61ba55bcSBaptiste Daroussin /* avoid menurows overflow and menurows becomes "at most menurows" */ 438*61ba55bcSBaptiste Daroussin if (d->h - BORDERS - htext - HBUTTONS <= 2 /* menuborders */) 439*61ba55bcSBaptiste Daroussin m->menurows = (m->nitems > 0) ? 1 : 0; /* widget_checksize() */ 440b319d934SAlfonso S. Siciliano else 441*61ba55bcSBaptiste Daroussin m->menurows = MIN(d->h - BORDERS - htext - HBUTTONS, hmenu) - 2; 442263660c0SAlfonso Siciliano 443*61ba55bcSBaptiste Daroussin /* 444*61ba55bcSBaptiste Daroussin * no minw=linelen to avoid big menu fault, then some col can be 445*61ba55bcSBaptiste Daroussin * hidden (example portconfig www/apache24). 446*61ba55bcSBaptiste Daroussin */ 447*61ba55bcSBaptiste Daroussin if (widget_checksize(d->h, d->w, &d->bs, 448*61ba55bcSBaptiste Daroussin 2 /* border box */ + MIN(m->menurows, 1), 0) != 0) 449*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 450*61ba55bcSBaptiste Daroussin 451*61ba55bcSBaptiste Daroussin if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0) 452*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 45384823cc7SAlfonso S. Siciliano 454263660c0SAlfonso Siciliano return (0); 455c76f0793SBaptiste Daroussin } 456c76f0793SBaptiste Daroussin 457*61ba55bcSBaptiste Daroussin static int mixedlist_redraw(struct dialog *d, struct privatemenu *m) 458c76f0793SBaptiste Daroussin { 459*61ba55bcSBaptiste Daroussin if (d->built) { 460*61ba55bcSBaptiste Daroussin hide_dialog(d); 461*61ba55bcSBaptiste Daroussin refresh(); /* Important for decreasing screen */ 462*61ba55bcSBaptiste Daroussin } 463*61ba55bcSBaptiste Daroussin m->menurows = m->apimenurows; 464*61ba55bcSBaptiste Daroussin if (menu_size_position(d, m) != 0) 465*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 466*61ba55bcSBaptiste Daroussin if (draw_dialog(d) != 0) 467*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 468*61ba55bcSBaptiste Daroussin if (d->built) 469*61ba55bcSBaptiste Daroussin refresh(); /* Important to fix grey lines expanding screen */ 470*61ba55bcSBaptiste Daroussin TEXTPAD(d, 2/*bmenu*/ + m->menurows + HBUTTONS); 471c76f0793SBaptiste Daroussin 472*61ba55bcSBaptiste Daroussin /* selected item in view*/ 473*61ba55bcSBaptiste Daroussin if (m->ypad > m->sel && m->ypad > 0) 474*61ba55bcSBaptiste Daroussin m->ypad = m->sel; 475*61ba55bcSBaptiste Daroussin if ((int)(m->ypad + m->menurows) <= m->sel) 476*61ba55bcSBaptiste Daroussin m->ypad = m->sel - m->menurows + 1; 477*61ba55bcSBaptiste Daroussin /* lower pad after a terminal expansion */ 478*61ba55bcSBaptiste Daroussin if (m->ypad > 0 && (m->nitems - m->ypad) < (int)m->menurows) 479*61ba55bcSBaptiste Daroussin m->ypad = m->nitems - m->menurows; 480c76f0793SBaptiste Daroussin 481*61ba55bcSBaptiste Daroussin update_box(d->conf, m->box, d->y + d->h - 5 - m->menurows, d->x + 2, 482*61ba55bcSBaptiste Daroussin m->menurows+2, d->w-4, LOWERED); 483*61ba55bcSBaptiste Daroussin update_menubox(d->conf, m); 484*61ba55bcSBaptiste Daroussin wnoutrefresh(m->box); 485c76f0793SBaptiste Daroussin 486*61ba55bcSBaptiste Daroussin m->ys = d->y + d->h - 5 - m->menurows + 1; 487*61ba55bcSBaptiste Daroussin m->ye = d->y + d->h - 5 ; 488*61ba55bcSBaptiste Daroussin if (d->conf->menu.align_left || (int)m->line > d->w - 6) { 489*61ba55bcSBaptiste Daroussin m->xs = d->x + 3; 490*61ba55bcSBaptiste Daroussin m->xe = m->xs + d->w - 7; 491*61ba55bcSBaptiste Daroussin } else { /* center */ 492*61ba55bcSBaptiste Daroussin m->xs = d->x + 3 + (d->w-6)/2 - m->line/2; 493*61ba55bcSBaptiste Daroussin m->xe = m->xs + d->w - 5; 494*61ba55bcSBaptiste Daroussin } 495*61ba55bcSBaptiste Daroussin drawseparators(d->conf, m); /* uses xe - xs */ 496*61ba55bcSBaptiste 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 { 506*61ba55bcSBaptiste Daroussin bool loop, changeitem; 507*61ba55bcSBaptiste Daroussin int i, next, retval; 508b319d934SAlfonso S. Siciliano wint_t input; 509*61ba55bcSBaptiste Daroussin struct privatemenu m; 510*61ba55bcSBaptiste Daroussin struct dialog d; 511c76f0793SBaptiste Daroussin 512*61ba55bcSBaptiste Daroussin if (prepare_dialog(conf, text, rows, cols, &d) != 0) 513263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 514*61ba55bcSBaptiste Daroussin set_buttons(&d, conf->menu.shortcut_buttons, OK_LABEL, CANCEL_LABEL); 515*61ba55bcSBaptiste Daroussin if (d.conf->menu.no_name && d.conf->menu.no_desc) 516*61ba55bcSBaptiste Daroussin RETURN_ERROR("Both conf.menu.no_name and conf.menu.no_desc"); 517*61ba55bcSBaptiste Daroussin 518*61ba55bcSBaptiste Daroussin if (build_privatemenu(conf, &m, mode, ngroups, groups) != 0) 519263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 520c76f0793SBaptiste Daroussin 521*61ba55bcSBaptiste Daroussin if ((m.box = newwin(1, 1, 1, 1)) == NULL) 522*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot build WINDOW box menu"); 523*61ba55bcSBaptiste Daroussin wbkgd(m.box, t.dialog.color); 524*61ba55bcSBaptiste Daroussin m.pad = newpad(m.nitems, m.line); 525*61ba55bcSBaptiste Daroussin wbkgd(m.pad, t.dialog.color); 526c76f0793SBaptiste Daroussin 527*61ba55bcSBaptiste Daroussin for (i = 0; i < m.nitems; i++) 528*61ba55bcSBaptiste Daroussin drawitem(conf, &m, i, false); 529*61ba55bcSBaptiste Daroussin m.sel = getfirst_with_default(m.nitems, m.pritems, ngroups, groups, 530263660c0SAlfonso Siciliano focuslist, focusitem); 531*61ba55bcSBaptiste Daroussin if (m.sel >= 0) 532*61ba55bcSBaptiste Daroussin drawitem(d.conf, &m, m.sel, true); 533*61ba55bcSBaptiste Daroussin m.ypad = 0; 534*61ba55bcSBaptiste Daroussin m.apimenurows = menurows; 535*61ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 536*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 537c76f0793SBaptiste Daroussin 538*61ba55bcSBaptiste Daroussin changeitem = false; 539c76f0793SBaptiste Daroussin loop = true; 540c76f0793SBaptiste Daroussin while (loop) { 541*61ba55bcSBaptiste 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 */ 547*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 548*61ba55bcSBaptiste Daroussin if (m.sel >= 0 && m.pritems[m.sel].type == MENUMODE) 549*61ba55bcSBaptiste 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; 555*61ba55bcSBaptiste Daroussin if (m.sel >= 0 && 556*61ba55bcSBaptiste Daroussin m.pritems[m.sel].type == MENUMODE) 557*61ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 558c76f0793SBaptiste Daroussin loop = false; 559263660c0SAlfonso Siciliano } 560c76f0793SBaptiste Daroussin break; 561c76f0793SBaptiste Daroussin case '\t': /* TAB */ 562*61ba55bcSBaptiste Daroussin case KEY_RIGHT: 563*61ba55bcSBaptiste Daroussin d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons; 564*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 565c76f0793SBaptiste Daroussin break; 566c76f0793SBaptiste Daroussin case KEY_LEFT: 567*61ba55bcSBaptiste Daroussin d.bs.curr--; 568*61ba55bcSBaptiste Daroussin if (d.bs.curr < 0) 569*61ba55bcSBaptiste Daroussin d.bs.curr = d.bs.nbuttons - 1; 570*61ba55bcSBaptiste 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; 576*61ba55bcSBaptiste Daroussin if (f1help_dialog(conf) != 0) 577263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 578*61ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 579*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 580*61ba55bcSBaptiste Daroussin break; 581c76f0793SBaptiste Daroussin case KEY_RESIZE: 582*61ba55bcSBaptiste Daroussin if (mixedlist_redraw(&d, &m) != 0) 583263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 584c76f0793SBaptiste Daroussin break; 585c76f0793SBaptiste Daroussin } 586c76f0793SBaptiste Daroussin 587*61ba55bcSBaptiste Daroussin if (m.sel < 0) 588c76f0793SBaptiste Daroussin continue; 589c76f0793SBaptiste Daroussin switch(input) { 590c76f0793SBaptiste Daroussin case KEY_HOME: 591*61ba55bcSBaptiste Daroussin next = getnext(m.nitems, m.pritems, -1); 592*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 593c76f0793SBaptiste Daroussin break; 594263660c0SAlfonso Siciliano case KEY_UP: 595*61ba55bcSBaptiste Daroussin next = getprev(m.pritems, m.sel); 596*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 597263660c0SAlfonso Siciliano break; 598263660c0SAlfonso Siciliano case KEY_PPAGE: 599*61ba55bcSBaptiste Daroussin next = getfastprev(m.menurows, m.pritems, m.sel); 600*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 601c76f0793SBaptiste Daroussin break; 602c76f0793SBaptiste Daroussin case KEY_END: 603*61ba55bcSBaptiste Daroussin next = getprev(m.pritems, m.nitems); 604*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 605263660c0SAlfonso Siciliano break; 606c76f0793SBaptiste Daroussin case KEY_DOWN: 607*61ba55bcSBaptiste Daroussin next = getnext(m.nitems, m.pritems, m.sel); 608*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 609263660c0SAlfonso Siciliano break; 610c76f0793SBaptiste Daroussin case KEY_NPAGE: 611*61ba55bcSBaptiste Daroussin next = getfastnext(m.menurows, m.nitems, m.pritems, m.sel); 612*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 613c76f0793SBaptiste Daroussin break; 614c76f0793SBaptiste Daroussin case ' ': /* Space */ 615*61ba55bcSBaptiste Daroussin if (m.pritems[m.sel].type == MENUMODE) { 616*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 617*61ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 61884823cc7SAlfonso S. Siciliano loop = false; 619*61ba55bcSBaptiste Daroussin } else if (m.pritems[m.sel].type == CHECKLISTMODE) { 620*61ba55bcSBaptiste Daroussin m.pritems[m.sel].on = !m.pritems[m.sel].on; 62184823cc7SAlfonso S. Siciliano } else { /* RADIOLISTMODE */ 622*61ba55bcSBaptiste Daroussin for (i = m.sel - m.pritems[m.sel].index; 623*61ba55bcSBaptiste Daroussin i < m.nitems && 624*61ba55bcSBaptiste Daroussin m.pritems[i].group == m.pritems[m.sel].group; 625263660c0SAlfonso Siciliano i++) { 626*61ba55bcSBaptiste Daroussin if (i != m.sel && m.pritems[i].on) { 627*61ba55bcSBaptiste Daroussin m.pritems[i].on = false; 628*61ba55bcSBaptiste Daroussin drawitem(conf, &m, i, false); 629c76f0793SBaptiste Daroussin } 630c76f0793SBaptiste Daroussin } 631*61ba55bcSBaptiste Daroussin m.pritems[m.sel].on = !m.pritems[m.sel].on; 632263660c0SAlfonso Siciliano } 633*61ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, true); 634*61ba55bcSBaptiste Daroussin pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe); 635263660c0SAlfonso Siciliano break; 6368c4f4028SBaptiste Daroussin default: 637*61ba55bcSBaptiste Daroussin if (conf->menu.shortcut_buttons) { 638*61ba55bcSBaptiste Daroussin if (shortcut_buttons(input, &d.bs)) { 639*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 640*61ba55bcSBaptiste Daroussin doupdate(); 641*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 642*61ba55bcSBaptiste Daroussin if (m.pritems[m.sel].type == MENUMODE) 643*61ba55bcSBaptiste Daroussin m.pritems[m.sel].on = true; 6448c4f4028SBaptiste Daroussin loop = false; 6458c4f4028SBaptiste Daroussin } 6468c4f4028SBaptiste Daroussin break; 6478c4f4028SBaptiste Daroussin } 6488c4f4028SBaptiste Daroussin 649263660c0SAlfonso Siciliano /* shourtcut items */ 650*61ba55bcSBaptiste Daroussin next = getnextshortcut(m.nitems, m.pritems, m.sel, 651263660c0SAlfonso Siciliano input); 652*61ba55bcSBaptiste Daroussin changeitem = next != m.sel; 653*61ba55bcSBaptiste Daroussin } /* end switch get_wch() */ 654263660c0SAlfonso Siciliano 655*61ba55bcSBaptiste Daroussin if (changeitem) { 656*61ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, false); 657*61ba55bcSBaptiste Daroussin m.sel = next; 658*61ba55bcSBaptiste Daroussin drawitem(conf, &m, m.sel, true); 659*61ba55bcSBaptiste Daroussin if (m.ypad > m.sel && m.ypad > 0) 660*61ba55bcSBaptiste Daroussin m.ypad = m.sel; 661*61ba55bcSBaptiste Daroussin if ((int)(m.ypad + m.menurows) <= m.sel) 662*61ba55bcSBaptiste Daroussin m.ypad = m.sel - m.menurows + 1; 663*61ba55bcSBaptiste Daroussin update_menubox(conf, &m); 664*61ba55bcSBaptiste Daroussin wnoutrefresh(m.box); 665*61ba55bcSBaptiste Daroussin pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe); 666*61ba55bcSBaptiste Daroussin changeitem = false; 667c76f0793SBaptiste Daroussin } 668*61ba55bcSBaptiste Daroussin } /* end while(loop) */ 669*61ba55bcSBaptiste Daroussin 670*61ba55bcSBaptiste Daroussin set_return_on(&m, groups); 671c76f0793SBaptiste Daroussin 672c76f0793SBaptiste Daroussin if (focuslist != NULL) 673*61ba55bcSBaptiste Daroussin *focuslist = m.sel < 0 ? -1 : m.pritems[m.sel].group; 674c76f0793SBaptiste Daroussin if (focusitem !=NULL) 675*61ba55bcSBaptiste Daroussin *focusitem = m.sel < 0 ? -1 : m.pritems[m.sel].index; 676c76f0793SBaptiste Daroussin 677*61ba55bcSBaptiste Daroussin if (m.hasbottomdesc && conf->clear) { 678*61ba55bcSBaptiste Daroussin move(SCREENLINES - 1, 2); 679*61ba55bcSBaptiste Daroussin clrtoeol(); 680*61ba55bcSBaptiste Daroussin } 681*61ba55bcSBaptiste Daroussin delwin(m.pad); 682*61ba55bcSBaptiste Daroussin delwin(m.box); 683*61ba55bcSBaptiste Daroussin end_dialog(&d); 684*61ba55bcSBaptiste Daroussin free(m.pritems); 685c76f0793SBaptiste Daroussin 686b319d934SAlfonso S. Siciliano return (retval); 687c76f0793SBaptiste Daroussin } 688c76f0793SBaptiste Daroussin 689263660c0SAlfonso Siciliano /* API */ 690263660c0SAlfonso Siciliano int 691263660c0SAlfonso Siciliano bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, 692263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int ngroups, 693263660c0SAlfonso Siciliano struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) 694c76f0793SBaptiste Daroussin { 695b319d934SAlfonso S. Siciliano int retval; 696c76f0793SBaptiste Daroussin 697b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE, 698c76f0793SBaptiste Daroussin ngroups, groups, focuslist, focusitem); 699c76f0793SBaptiste Daroussin 700b319d934SAlfonso S. Siciliano return (retval); 701c76f0793SBaptiste Daroussin } 702c76f0793SBaptiste Daroussin 703c76f0793SBaptiste Daroussin int 704263660c0SAlfonso Siciliano bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows, 705263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 706263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 707c76f0793SBaptiste Daroussin { 708b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 709c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 710*61ba55bcSBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items, 0}; 711c76f0793SBaptiste Daroussin 712*61ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 713b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE, 714263660c0SAlfonso Siciliano 1, &group, &focuslist, focusitem); 715c76f0793SBaptiste Daroussin 716b319d934SAlfonso S. Siciliano return (retval); 717c76f0793SBaptiste Daroussin } 718c76f0793SBaptiste Daroussin 719c76f0793SBaptiste Daroussin int 720263660c0SAlfonso Siciliano bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows, 721263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 722263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 723c76f0793SBaptiste Daroussin { 724b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 725c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 726*61ba55bcSBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items, 0}; 727c76f0793SBaptiste Daroussin 728*61ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 729b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1, 730263660c0SAlfonso Siciliano &group, &focuslist, focusitem); 731c76f0793SBaptiste Daroussin 732b319d934SAlfonso S. Siciliano return (retval); 733c76f0793SBaptiste Daroussin } 734c76f0793SBaptiste Daroussin 735c76f0793SBaptiste Daroussin int 736263660c0SAlfonso Siciliano bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows, 737263660c0SAlfonso Siciliano int cols, unsigned int menurows, unsigned int nitems, 738263660c0SAlfonso Siciliano struct bsddialog_menuitem *items, int *focusitem) 739c76f0793SBaptiste Daroussin { 740b319d934SAlfonso S. Siciliano int retval, focuslist = 0; 741c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 742*61ba55bcSBaptiste Daroussin BSDDIALOG_RADIOLIST /* unused */, nitems, items, 0}; 743c76f0793SBaptiste Daroussin 744*61ba55bcSBaptiste Daroussin CHECK_ARRAY(nitems, items); /* efficiency, avoid do_mixedlist() */ 745b319d934SAlfonso S. Siciliano retval = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE, 746263660c0SAlfonso Siciliano 1, &group, &focuslist, focusitem); 747c76f0793SBaptiste Daroussin 748b319d934SAlfonso S. Siciliano return (retval); 749c76f0793SBaptiste Daroussin } 750