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
getmode(enum menumode mode,struct bsddialog_menugroup group)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
build_privatemenu(struct bsddialog_conf * conf,struct privatemenu * m,enum menumode mode,unsigned int ngroups,struct bsddialog_menugroup * groups)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
set_return_on(struct privatemenu * m,struct bsddialog_menugroup * groups)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
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)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
drawseparators(struct bsddialog_conf * conf,struct privatemenu * m)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
drawitem(struct bsddialog_conf * conf,struct privatemenu * m,int y,bool focus)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
update_menubox(struct bsddialog_conf * conf,struct privatemenu * m)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
menu_size_position(struct dialog * d,struct privatemenu * m)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
mixedlist_redraw(struct dialog * d,struct privatemenu * m)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
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 {
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
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)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
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)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
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)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
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)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