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
getmode(enum menumode mode,struct bsddialog_menugroup group)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
build_privatemenu(struct bsddialog_conf * conf,struct privatemenu * m,enum menumode mode,unsigned int ngroups,struct bsddialog_menugroup * groups)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
set_return_on(struct privatemenu * m,struct bsddialog_menugroup * groups)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
getprev(struct privateitem * pritems,int abs)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
getnext(int npritems,struct privateitem * pritems,int abs)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
getfirst_with_default(int npritems,struct privateitem * pritems,int ngroups,struct bsddialog_menugroup * groups,int * focusgroup,int * focusitem)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
getfastnext(int menurows,int npritems,struct privateitem * pritems,int abs)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
getfastprev(int menurows,struct privateitem * pritems,int abs)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
getnextshortcut(int npritems,struct privateitem * pritems,int abs,wint_t key)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
drawseparators(struct bsddialog_conf * conf,struct privatemenu * m)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
drawitem(struct bsddialog_conf * conf,struct privatemenu * m,int y,bool focus)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
update_menubox(struct bsddialog_conf * conf,struct privatemenu * m)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
menu_size_position(struct dialog * d,struct privatemenu * m)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
mixedlist_redraw(struct dialog * d,struct privatemenu * m)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
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)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
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)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
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)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
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)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
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)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