1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4c76f0793SBaptiste Daroussin * Copyright (c) 2021 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 28c76f0793SBaptiste Daroussin #include <sys/param.h> 29c76f0793SBaptiste Daroussin 30c76f0793SBaptiste Daroussin #include <ctype.h> 31c76f0793SBaptiste Daroussin #ifdef PORTNCURSES 328c4f4028SBaptiste Daroussin #include <ncurses/ncurses.h> 33c76f0793SBaptiste Daroussin #else 348c4f4028SBaptiste Daroussin #include <ncurses.h> 35c76f0793SBaptiste Daroussin #endif 36*d93b4d32SBaptiste Daroussin #include <string.h> 37*d93b4d32SBaptiste Daroussin 38c76f0793SBaptiste Daroussin 39c76f0793SBaptiste Daroussin #include "bsddialog.h" 40c76f0793SBaptiste Daroussin #include "lib_util.h" 41c76f0793SBaptiste Daroussin #include "bsddialog_theme.h" 42c76f0793SBaptiste Daroussin 43f499134dSBaptiste Daroussin /* "Menu": checklist - menu - mixedlist - radiolist - buildlist */ 44c76f0793SBaptiste Daroussin 45c76f0793SBaptiste Daroussin #define DEPTHSPACE 4 46c76f0793SBaptiste Daroussin #define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */ 47c76f0793SBaptiste Daroussin 48c76f0793SBaptiste Daroussin extern struct bsddialog_theme t; 49c76f0793SBaptiste Daroussin 50c76f0793SBaptiste Daroussin enum menumode { 51c76f0793SBaptiste Daroussin BUILDLISTMODE, 52c76f0793SBaptiste Daroussin CHECKLISTMODE, 53c76f0793SBaptiste Daroussin MENUMODE, 54c76f0793SBaptiste Daroussin MIXEDLISTMODE, 55c76f0793SBaptiste Daroussin RADIOLISTMODE, 56c76f0793SBaptiste Daroussin SEPARATORMODE 57c76f0793SBaptiste Daroussin }; 58c76f0793SBaptiste Daroussin 59c76f0793SBaptiste Daroussin struct lineposition { 60c76f0793SBaptiste Daroussin unsigned int maxsepstr; 61c76f0793SBaptiste Daroussin unsigned int maxprefix; 62c76f0793SBaptiste Daroussin unsigned int xselector; 63c76f0793SBaptiste Daroussin unsigned int selectorlen; 64c76f0793SBaptiste Daroussin unsigned int maxdepth; 65c76f0793SBaptiste Daroussin unsigned int xname; 66c76f0793SBaptiste Daroussin unsigned int maxname; 67c76f0793SBaptiste Daroussin unsigned int xdesc; 68c76f0793SBaptiste Daroussin unsigned int maxdesc; 69c76f0793SBaptiste Daroussin unsigned int line; 70c76f0793SBaptiste Daroussin }; 71c76f0793SBaptiste Daroussin 72c76f0793SBaptiste Daroussin static int checkradiolist(int nitems, struct bsddialog_menuitem *items) 73c76f0793SBaptiste Daroussin { 74c76f0793SBaptiste Daroussin int i, error; 75c76f0793SBaptiste Daroussin 76c76f0793SBaptiste Daroussin error = 0; 77c76f0793SBaptiste Daroussin for (i=0; i<nitems; i++) { 78c76f0793SBaptiste Daroussin if (error > 0) 79c76f0793SBaptiste Daroussin items[i].on = false; 80c76f0793SBaptiste Daroussin 81c76f0793SBaptiste Daroussin if (items[i].on == true) 82c76f0793SBaptiste Daroussin error++; 83c76f0793SBaptiste Daroussin } 84c76f0793SBaptiste Daroussin 85c76f0793SBaptiste Daroussin return (error == 0 ? 0 : -1); 86c76f0793SBaptiste Daroussin } 87c76f0793SBaptiste Daroussin 88c76f0793SBaptiste Daroussin static int checkmenu(int nitems, struct bsddialog_menuitem *items) // useful? 89c76f0793SBaptiste Daroussin { 90c76f0793SBaptiste Daroussin int i, error; 91c76f0793SBaptiste Daroussin 92c76f0793SBaptiste Daroussin error = 0; 93c76f0793SBaptiste Daroussin for (i=0; i<nitems; i++) { 94c76f0793SBaptiste Daroussin if (items[i].on == true) 95c76f0793SBaptiste Daroussin error++; 96c76f0793SBaptiste Daroussin 97c76f0793SBaptiste Daroussin items[i].on = false; 98c76f0793SBaptiste Daroussin } 99c76f0793SBaptiste Daroussin 100c76f0793SBaptiste Daroussin return (error == 0 ? 0 : -1); 101c76f0793SBaptiste Daroussin } 102c76f0793SBaptiste Daroussin 103c76f0793SBaptiste Daroussin static void 104c76f0793SBaptiste Daroussin getfirst(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group, 105c76f0793SBaptiste Daroussin int *rel) 106c76f0793SBaptiste Daroussin { 107c76f0793SBaptiste Daroussin int i, a; 108c76f0793SBaptiste Daroussin 109c76f0793SBaptiste Daroussin *abs = *rel = *group = -1; 110c76f0793SBaptiste Daroussin a = 0; 111c76f0793SBaptiste Daroussin for (i=0; i<ngroups; i++) { 112c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 113c76f0793SBaptiste Daroussin a += groups[i].nitems; 114c76f0793SBaptiste Daroussin continue; 115c76f0793SBaptiste Daroussin } 116c76f0793SBaptiste Daroussin if (groups[i].nitems != 0) { 117c76f0793SBaptiste Daroussin *group = i; 118c76f0793SBaptiste Daroussin *abs = a; 119c76f0793SBaptiste Daroussin *rel = 0; 120c76f0793SBaptiste Daroussin break; 121c76f0793SBaptiste Daroussin } 122c76f0793SBaptiste Daroussin } 123c76f0793SBaptiste Daroussin } 124c76f0793SBaptiste Daroussin 125c76f0793SBaptiste Daroussin static void 126f499134dSBaptiste Daroussin getfirst_with_default(struct bsddialog_conf *conf, int ngroups, 127c76f0793SBaptiste Daroussin struct bsddialog_menugroup *groups, int *abs, int *group, int *rel) 128c76f0793SBaptiste Daroussin { 129c76f0793SBaptiste Daroussin int i, j, a; 130c76f0793SBaptiste Daroussin struct bsddialog_menuitem *item; 131c76f0793SBaptiste Daroussin 132c76f0793SBaptiste Daroussin getfirst(ngroups, groups, abs, group, rel); 133c76f0793SBaptiste Daroussin if (*abs < 0) 134c76f0793SBaptiste Daroussin return; 135c76f0793SBaptiste Daroussin 136c76f0793SBaptiste Daroussin a = *abs; 137c76f0793SBaptiste Daroussin 138c76f0793SBaptiste Daroussin for (i=*group; i<ngroups; i++) { 139c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 140c76f0793SBaptiste Daroussin a += groups[i].nitems; 141c76f0793SBaptiste Daroussin continue; 142c76f0793SBaptiste Daroussin } 143c76f0793SBaptiste Daroussin for (j = 0; j < (int) groups[i].nitems; j++) { 144c76f0793SBaptiste Daroussin item = &groups[i].items[j]; 145f499134dSBaptiste Daroussin if (conf->menu.default_item != NULL && item->name != NULL) { 146f499134dSBaptiste Daroussin if (strcmp(item->name, conf->menu.default_item) == 0) { 147c76f0793SBaptiste Daroussin *abs = a; 148c76f0793SBaptiste Daroussin *group = i; 149c76f0793SBaptiste Daroussin *rel = j; 150c76f0793SBaptiste Daroussin return; 151c76f0793SBaptiste Daroussin } 152c76f0793SBaptiste Daroussin } 153c76f0793SBaptiste Daroussin a++; 154c76f0793SBaptiste Daroussin } 155c76f0793SBaptiste Daroussin } 156c76f0793SBaptiste Daroussin } 157c76f0793SBaptiste Daroussin 158c76f0793SBaptiste Daroussin static void 159c76f0793SBaptiste Daroussin getlast(int totnitems, int ngroups, struct bsddialog_menugroup *groups, 160c76f0793SBaptiste Daroussin int *abs, int *group, int *rel) 161c76f0793SBaptiste Daroussin { 162c76f0793SBaptiste Daroussin int i, a; 163c76f0793SBaptiste Daroussin 164c76f0793SBaptiste Daroussin a = totnitems - 1; 165c76f0793SBaptiste Daroussin for (i = ngroups-1; i>=0; i--) { 166c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 167c76f0793SBaptiste Daroussin a -= groups[i].nitems; 168c76f0793SBaptiste Daroussin continue; 169c76f0793SBaptiste Daroussin } 170c76f0793SBaptiste Daroussin if (groups[i].nitems != 0) { 171c76f0793SBaptiste Daroussin *group = i; 172c76f0793SBaptiste Daroussin *abs = a; 173c76f0793SBaptiste Daroussin *rel = groups[i].nitems - 1; 174c76f0793SBaptiste Daroussin break; 175c76f0793SBaptiste Daroussin } 176c76f0793SBaptiste Daroussin } 177c76f0793SBaptiste Daroussin } 178c76f0793SBaptiste Daroussin 179c76f0793SBaptiste Daroussin static void 180c76f0793SBaptiste Daroussin getnext(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group, 181c76f0793SBaptiste Daroussin int *rel) 182c76f0793SBaptiste Daroussin { 183c76f0793SBaptiste Daroussin int i, a; 184c76f0793SBaptiste Daroussin 185c76f0793SBaptiste Daroussin if (*abs < 0 || *group < 0 || *rel < 0) 186c76f0793SBaptiste Daroussin return; 187c76f0793SBaptiste Daroussin 188c76f0793SBaptiste Daroussin if (*rel + 1 < (int) groups[*group].nitems) { 189c76f0793SBaptiste Daroussin *rel = *rel + 1; 190c76f0793SBaptiste Daroussin *abs = *abs + 1; 191c76f0793SBaptiste Daroussin return; 192c76f0793SBaptiste Daroussin } 193c76f0793SBaptiste Daroussin 194c76f0793SBaptiste Daroussin if (*group + 1 > ngroups) 195c76f0793SBaptiste Daroussin return; 196c76f0793SBaptiste Daroussin 197c76f0793SBaptiste Daroussin a = *abs; 198c76f0793SBaptiste Daroussin for (i = *group + 1; i < ngroups; i++) { 199c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 200c76f0793SBaptiste Daroussin a += groups[i].nitems; 201c76f0793SBaptiste Daroussin continue; 202c76f0793SBaptiste Daroussin } 203c76f0793SBaptiste Daroussin if (groups[i].nitems != 0) { 204c76f0793SBaptiste Daroussin *group = i; 205c76f0793SBaptiste Daroussin *abs = a + 1; 206c76f0793SBaptiste Daroussin *rel = 0; 207c76f0793SBaptiste Daroussin break; 208c76f0793SBaptiste Daroussin } 209c76f0793SBaptiste Daroussin } 210c76f0793SBaptiste Daroussin } 211c76f0793SBaptiste Daroussin 212c76f0793SBaptiste Daroussin static void 213c76f0793SBaptiste Daroussin getfastnext(int menurows, int ngroups, struct bsddialog_menugroup *groups, 214c76f0793SBaptiste Daroussin int *abs, int *group, int *rel) 215c76f0793SBaptiste Daroussin { 216c76f0793SBaptiste Daroussin int a, start, i; 217c76f0793SBaptiste Daroussin 218c76f0793SBaptiste Daroussin start = *abs; 219c76f0793SBaptiste Daroussin i = menurows; 220c76f0793SBaptiste Daroussin do { 221c76f0793SBaptiste Daroussin a = *abs; 222c76f0793SBaptiste Daroussin getnext(ngroups, groups, abs, group, rel); 223c76f0793SBaptiste Daroussin i--; 224c76f0793SBaptiste Daroussin } while (*abs != a && *abs < start + menurows && i > 0); 225c76f0793SBaptiste Daroussin } 226c76f0793SBaptiste Daroussin 227c76f0793SBaptiste Daroussin static void 228c76f0793SBaptiste Daroussin getprev(struct bsddialog_menugroup *groups, int *abs, int *group, int *rel) 229c76f0793SBaptiste Daroussin { 230c76f0793SBaptiste Daroussin int i, a; 231c76f0793SBaptiste Daroussin 232c76f0793SBaptiste Daroussin if (*abs < 0 || *group < 0 || *rel < 0) 233c76f0793SBaptiste Daroussin return; 234c76f0793SBaptiste Daroussin 235c76f0793SBaptiste Daroussin if (*rel > 0) { 236c76f0793SBaptiste Daroussin *rel = *rel - 1; 237c76f0793SBaptiste Daroussin *abs = *abs - 1; 238c76f0793SBaptiste Daroussin return; 239c76f0793SBaptiste Daroussin } 240c76f0793SBaptiste Daroussin 241c76f0793SBaptiste Daroussin if (*group - 1 < 0) 242c76f0793SBaptiste Daroussin return; 243c76f0793SBaptiste Daroussin 244c76f0793SBaptiste Daroussin a = *abs; 245c76f0793SBaptiste Daroussin for (i = *group - 1; i >= 0; i--) { 246c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 247c76f0793SBaptiste Daroussin a -= (int) groups[i].nitems; 248c76f0793SBaptiste Daroussin continue; 249c76f0793SBaptiste Daroussin } 250c76f0793SBaptiste Daroussin if (groups[i].nitems != 0) { 251c76f0793SBaptiste Daroussin *group = i; 252c76f0793SBaptiste Daroussin *abs = a - 1; 253c76f0793SBaptiste Daroussin *rel = (int) groups[i].nitems - 1; 254c76f0793SBaptiste Daroussin break; 255c76f0793SBaptiste Daroussin } 256c76f0793SBaptiste Daroussin } 257c76f0793SBaptiste Daroussin } 258c76f0793SBaptiste Daroussin 259c76f0793SBaptiste Daroussin static void 260c76f0793SBaptiste Daroussin getfastprev(int menurows, struct bsddialog_menugroup *groups, int *abs, 261c76f0793SBaptiste Daroussin int *group, int *rel) 262c76f0793SBaptiste Daroussin { 263c76f0793SBaptiste Daroussin int a, start, i; 264c76f0793SBaptiste Daroussin 265c76f0793SBaptiste Daroussin start = *abs; 266c76f0793SBaptiste Daroussin i = menurows; 267c76f0793SBaptiste Daroussin do { 268c76f0793SBaptiste Daroussin a = *abs; 269c76f0793SBaptiste Daroussin getprev(groups, abs, group, rel); 270c76f0793SBaptiste Daroussin i--; 271c76f0793SBaptiste Daroussin } while (*abs != a && *abs > start - menurows && i > 0); 272c76f0793SBaptiste Daroussin } 273c76f0793SBaptiste Daroussin 2748c4f4028SBaptiste Daroussin static bool 2758c4f4028SBaptiste Daroussin getnextshortcut(struct bsddialog_conf *conf, enum menumode mode, int ngroups, 2768c4f4028SBaptiste Daroussin struct bsddialog_menugroup *groups, int *abs, int *group, int *rel, 2778c4f4028SBaptiste Daroussin int key) 2788c4f4028SBaptiste Daroussin { 2798c4f4028SBaptiste Daroussin int i, j, a, ch, ng, nr, na; 2808c4f4028SBaptiste Daroussin bool mainloop; 2818c4f4028SBaptiste Daroussin 2828c4f4028SBaptiste Daroussin if (*abs < 0 || ngroups < 0 || *rel < 0 || mode == BUILDLISTMODE) 2838c4f4028SBaptiste Daroussin return false; 2848c4f4028SBaptiste Daroussin 2858c4f4028SBaptiste Daroussin na = a = -1; 2868c4f4028SBaptiste Daroussin mainloop = true; 2878c4f4028SBaptiste Daroussin for (i = 0; i < ngroups && mainloop; i++) { 2888c4f4028SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 2898c4f4028SBaptiste Daroussin a += groups[i].nitems; 2908c4f4028SBaptiste Daroussin continue; 2918c4f4028SBaptiste Daroussin } 2928c4f4028SBaptiste Daroussin for (j = 0; j < (int)groups[i].nitems; j++) { 2938c4f4028SBaptiste Daroussin a++; 2948c4f4028SBaptiste Daroussin if (a == *abs) 2958c4f4028SBaptiste Daroussin continue; 2968c4f4028SBaptiste Daroussin 2978c4f4028SBaptiste Daroussin if (conf->menu.no_name) 2988c4f4028SBaptiste Daroussin ch = groups[i].items[j].desc[0]; 2998c4f4028SBaptiste Daroussin else 3008c4f4028SBaptiste Daroussin ch = groups[i].items[j].name[0]; 3018c4f4028SBaptiste Daroussin 3028c4f4028SBaptiste Daroussin if (ch == key) { 3038c4f4028SBaptiste Daroussin if (a < *abs && na == -1) { 3048c4f4028SBaptiste Daroussin na = a; 3058c4f4028SBaptiste Daroussin ng = i; 3068c4f4028SBaptiste Daroussin nr = j; 3078c4f4028SBaptiste Daroussin } 3088c4f4028SBaptiste Daroussin if (a > *abs) { 3098c4f4028SBaptiste Daroussin na = a; 3108c4f4028SBaptiste Daroussin ng = i; 3118c4f4028SBaptiste Daroussin nr = j; 3128c4f4028SBaptiste Daroussin mainloop = false; 3138c4f4028SBaptiste Daroussin break; 3148c4f4028SBaptiste Daroussin } 3158c4f4028SBaptiste Daroussin } 3168c4f4028SBaptiste Daroussin } 3178c4f4028SBaptiste Daroussin } 3188c4f4028SBaptiste Daroussin 3198c4f4028SBaptiste Daroussin if (na != -1) { 3208c4f4028SBaptiste Daroussin *abs = na; 3218c4f4028SBaptiste Daroussin *group = ng; 3228c4f4028SBaptiste Daroussin *rel = nr; 3238c4f4028SBaptiste Daroussin return (true); 3248c4f4028SBaptiste Daroussin } 3258c4f4028SBaptiste Daroussin 3268c4f4028SBaptiste Daroussin return (false); 3278c4f4028SBaptiste Daroussin } 3288c4f4028SBaptiste Daroussin 329c76f0793SBaptiste Daroussin static enum menumode 330c76f0793SBaptiste Daroussin getmode(enum menumode mode, struct bsddialog_menugroup group) 331c76f0793SBaptiste Daroussin { 332c76f0793SBaptiste Daroussin 333c76f0793SBaptiste Daroussin if (mode == MIXEDLISTMODE) { 334c76f0793SBaptiste Daroussin if (group.type == BSDDIALOG_SEPARATOR) 335c76f0793SBaptiste Daroussin mode = SEPARATORMODE; 336c76f0793SBaptiste Daroussin else if (group.type == BSDDIALOG_RADIOLIST) 337c76f0793SBaptiste Daroussin mode = RADIOLISTMODE; 338c76f0793SBaptiste Daroussin else if (group.type == BSDDIALOG_CHECKLIST) 339c76f0793SBaptiste Daroussin mode = CHECKLISTMODE; 340c76f0793SBaptiste Daroussin } 341c76f0793SBaptiste Daroussin 342c76f0793SBaptiste Daroussin return mode; 343c76f0793SBaptiste Daroussin } 344c76f0793SBaptiste Daroussin 345c76f0793SBaptiste Daroussin static void 346f499134dSBaptiste Daroussin drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y, 347c76f0793SBaptiste Daroussin struct bsddialog_menuitem item, enum menumode mode, struct lineposition pos, 348c76f0793SBaptiste Daroussin bool curr) 349c76f0793SBaptiste Daroussin { 3508c4f4028SBaptiste Daroussin int colordesc, colorname, colorshortcut, linech; 3518c4f4028SBaptiste Daroussin char *shortcut; 352c76f0793SBaptiste Daroussin 353c76f0793SBaptiste Daroussin if (mode == SEPARATORMODE) { 354f499134dSBaptiste Daroussin if (conf->no_lines == false) { 355f499134dSBaptiste Daroussin wattron(pad, t.menu.desccolor); 356f499134dSBaptiste Daroussin linech = conf->ascii_lines ? '-' : ACS_HLINE; 357c76f0793SBaptiste Daroussin mvwhline(pad, y, 0, linech, pos.line); 358f499134dSBaptiste Daroussin wattroff(pad, t.menu.desccolor); 359c76f0793SBaptiste Daroussin } 360c76f0793SBaptiste Daroussin wmove(pad, y, pos.line/2 - (strlen(item.name)+strlen(item.desc))/2); 361f499134dSBaptiste Daroussin wattron(pad, t.menu.namesepcolor); 362c76f0793SBaptiste Daroussin waddstr(pad, item.name); 363f499134dSBaptiste Daroussin wattroff(pad, t.menu.namesepcolor); 364c76f0793SBaptiste Daroussin if (strlen(item.name) > 0 && strlen(item.desc) > 0) 365c76f0793SBaptiste Daroussin waddch(pad, ' '); 366f499134dSBaptiste Daroussin wattron(pad, t.menu.descsepcolor); 367c76f0793SBaptiste Daroussin waddstr(pad, item.desc); 368f499134dSBaptiste Daroussin wattroff(pad, t.menu.descsepcolor); 369c76f0793SBaptiste Daroussin return; 370c76f0793SBaptiste Daroussin } 371c76f0793SBaptiste Daroussin 372c76f0793SBaptiste Daroussin /* prefix */ 373c76f0793SBaptiste Daroussin if (item.prefix != NULL && item.prefix[0] != '\0') 374c76f0793SBaptiste Daroussin mvwaddstr(pad, y, 0, item.prefix); 375c76f0793SBaptiste Daroussin 376c76f0793SBaptiste Daroussin /* selector */ 377c76f0793SBaptiste Daroussin wmove(pad, y, pos.xselector); 3788c4f4028SBaptiste Daroussin wattron(pad, t.menu.selectorcolor); 379c76f0793SBaptiste Daroussin if (mode == CHECKLISTMODE) 380c76f0793SBaptiste Daroussin wprintw(pad, "[%c]", item.on ? 'X' : ' '); 381c76f0793SBaptiste Daroussin if (mode == RADIOLISTMODE) 382c76f0793SBaptiste Daroussin wprintw(pad, "(%c)", item.on ? '*' : ' '); 3838c4f4028SBaptiste Daroussin wattroff(pad, t.menu.selectorcolor); 384c76f0793SBaptiste Daroussin 385c76f0793SBaptiste Daroussin /* name */ 3868c4f4028SBaptiste Daroussin colorname = curr ? t.menu.f_namecolor : t.menu.namecolor; 387f499134dSBaptiste Daroussin if (mode != BUILDLISTMODE && conf->menu.no_name == false) { 388c76f0793SBaptiste Daroussin wattron(pad, colorname); 389c76f0793SBaptiste Daroussin mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.name); 390c76f0793SBaptiste Daroussin wattroff(pad, colorname); 391c76f0793SBaptiste Daroussin } 392c76f0793SBaptiste Daroussin 393c76f0793SBaptiste Daroussin /* description */ 3948c4f4028SBaptiste Daroussin if (mode == BUILDLISTMODE) { 3958c4f4028SBaptiste Daroussin if (curr == false) 3968c4f4028SBaptiste Daroussin colordesc = item.on ? t.menu.namecolor : t.menu.desccolor; 3978c4f4028SBaptiste Daroussin else 3988c4f4028SBaptiste Daroussin colordesc = t.menu.f_namecolor; 3998c4f4028SBaptiste Daroussin } 4008c4f4028SBaptiste Daroussin else { 4018c4f4028SBaptiste Daroussin if (conf->menu.no_name) 4028c4f4028SBaptiste Daroussin colordesc = curr ? t.menu.f_namecolor : t.menu.namecolor; 4038c4f4028SBaptiste Daroussin else 4048c4f4028SBaptiste Daroussin colordesc = curr ? t.menu.f_desccolor : t.menu.desccolor; 4058c4f4028SBaptiste Daroussin } 4068c4f4028SBaptiste Daroussin if (mode == BUILDLISTMODE || conf->menu.no_desc == false) { 4078c4f4028SBaptiste Daroussin wattron(pad, colordesc); 408f499134dSBaptiste Daroussin if (conf->menu.no_name) 409c76f0793SBaptiste Daroussin mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.desc); 410c76f0793SBaptiste Daroussin else 411c76f0793SBaptiste Daroussin mvwaddstr(pad, y, pos.xdesc, item.desc); 4128c4f4028SBaptiste Daroussin wattroff(pad, colordesc); 413c76f0793SBaptiste Daroussin } 414c76f0793SBaptiste Daroussin 4158c4f4028SBaptiste Daroussin /* shortcut */ 4168c4f4028SBaptiste Daroussin if (mode != BUILDLISTMODE && conf->menu.shortcut_buttons == false) { 4178c4f4028SBaptiste Daroussin colorshortcut = curr ? t.menu.f_shortcutcolor : t.menu.shortcutcolor; 4188c4f4028SBaptiste Daroussin wattron(pad, colorshortcut); 4198c4f4028SBaptiste Daroussin 4208c4f4028SBaptiste Daroussin if (conf->menu.no_name) 4218c4f4028SBaptiste Daroussin shortcut = item.desc; 4228c4f4028SBaptiste Daroussin else 4238c4f4028SBaptiste Daroussin shortcut = item.name; 4248c4f4028SBaptiste Daroussin wmove(pad, y, pos.xname + item.depth * DEPTHSPACE); 4258c4f4028SBaptiste Daroussin if (shortcut != NULL && shortcut[0] != '\0') 4268c4f4028SBaptiste Daroussin waddch(pad, shortcut[0]); 4278c4f4028SBaptiste Daroussin wattroff(pad, colorshortcut); 4288c4f4028SBaptiste Daroussin } 4298c4f4028SBaptiste Daroussin 4308c4f4028SBaptiste Daroussin /* bottom description */ 431c76f0793SBaptiste Daroussin move(LINES-1, 2); 432c76f0793SBaptiste Daroussin clrtoeol(); 4338c4f4028SBaptiste Daroussin if (item.bottomdesc != NULL) { 434c76f0793SBaptiste Daroussin addstr(item.bottomdesc); 435c76f0793SBaptiste Daroussin refresh(); 436c76f0793SBaptiste Daroussin } 437c76f0793SBaptiste Daroussin } 438c76f0793SBaptiste Daroussin 439c76f0793SBaptiste Daroussin static void 440f499134dSBaptiste Daroussin menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, 441c76f0793SBaptiste Daroussin char *text, int linelen, unsigned int *menurows, int nitems, 442c76f0793SBaptiste Daroussin struct buttons bs) 443c76f0793SBaptiste Daroussin { 444c76f0793SBaptiste Daroussin int textrow, menusize; 445c76f0793SBaptiste Daroussin 446c76f0793SBaptiste Daroussin textrow = text != NULL && strlen(text) > 0 ? 1 : 0; 447c76f0793SBaptiste Daroussin 448c76f0793SBaptiste Daroussin if (cols == BSDDIALOG_AUTOSIZE) { 449c76f0793SBaptiste Daroussin *w = VBORDERS; 450c76f0793SBaptiste Daroussin /* buttons size */ 451c76f0793SBaptiste Daroussin *w += bs.nbuttons * bs.sizebutton; 452f499134dSBaptiste Daroussin *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 453c76f0793SBaptiste Daroussin /* line size */ 454c76f0793SBaptiste Daroussin *w = MAX(*w, linelen + 6); 4558c4f4028SBaptiste Daroussin /* conf.auto_minwidth */ 4568c4f4028SBaptiste Daroussin *w = MAX(*w, (int)conf->auto_minwidth); 457c76f0793SBaptiste Daroussin /* 458c76f0793SBaptiste Daroussin * avoid terminal overflow, 459c76f0793SBaptiste Daroussin * -1 fix false negative with big menu over the terminal and 460c76f0793SBaptiste Daroussin * autosize, for example "portconfig /usr/ports/www/apache24/". 461c76f0793SBaptiste Daroussin */ 462c76f0793SBaptiste Daroussin *w = MIN(*w, widget_max_width(conf)-1); 463c76f0793SBaptiste Daroussin } 464c76f0793SBaptiste Daroussin 465c76f0793SBaptiste Daroussin if (rows == BSDDIALOG_AUTOSIZE) { 466c76f0793SBaptiste Daroussin *h = HBORDERS + 2 /* buttons */ + textrow; 467c76f0793SBaptiste Daroussin 468c76f0793SBaptiste Daroussin if (*menurows == 0) { 469c76f0793SBaptiste Daroussin *h += nitems + 2; 470c76f0793SBaptiste Daroussin *h = MIN(*h, widget_max_height(conf)); 471c76f0793SBaptiste Daroussin menusize = MIN(nitems + 2, *h - (HBORDERS + 2 + textrow)); 472c76f0793SBaptiste Daroussin menusize -=2; 473c76f0793SBaptiste Daroussin *menurows = menusize < 0 ? 0 : menusize; 474c76f0793SBaptiste Daroussin } 475c76f0793SBaptiste Daroussin else /* h autosize with a fixed menurows */ 476c76f0793SBaptiste Daroussin *h = *h + *menurows + 2; 477c76f0793SBaptiste Daroussin 4788c4f4028SBaptiste Daroussin /* conf.auto_minheight */ 4798c4f4028SBaptiste Daroussin *h = MAX(*h, (int)conf->auto_minheight); 480c76f0793SBaptiste Daroussin /* avoid terminal overflow */ 481c76f0793SBaptiste Daroussin *h = MIN(*h, widget_max_height(conf)); 4828c4f4028SBaptiste Daroussin /* avoid menurows overflow */ 4838c4f4028SBaptiste Daroussin /* manual: with rows=autosize menurows!=0 is maxmenurows */ 4848c4f4028SBaptiste Daroussin *menurows = MIN(*h - 6 - textrow, (int)*menurows); 485c76f0793SBaptiste Daroussin } 486c76f0793SBaptiste Daroussin else { 487c76f0793SBaptiste Daroussin if (*menurows == 0) 488c76f0793SBaptiste Daroussin *menurows = MIN(rows-6-textrow, nitems); 489c76f0793SBaptiste Daroussin } 490c76f0793SBaptiste Daroussin } 491c76f0793SBaptiste Daroussin 492c76f0793SBaptiste Daroussin static int 493c76f0793SBaptiste Daroussin menu_checksize(int rows, int cols, char *text, int menurows, int nitems, 494c76f0793SBaptiste Daroussin struct buttons bs) 495c76f0793SBaptiste Daroussin { 496c76f0793SBaptiste Daroussin int mincols, textrow, menusize; 497c76f0793SBaptiste Daroussin 498c76f0793SBaptiste Daroussin mincols = VBORDERS; 499c76f0793SBaptiste Daroussin /* buttons */ 500c76f0793SBaptiste Daroussin mincols += bs.nbuttons * bs.sizebutton; 501f499134dSBaptiste Daroussin mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 502c76f0793SBaptiste Daroussin /* line, comment to permet some cols hidden */ 503c76f0793SBaptiste Daroussin /* mincols = MAX(mincols, linelen); */ 504c76f0793SBaptiste Daroussin 505c76f0793SBaptiste Daroussin if (cols < mincols) 506c76f0793SBaptiste Daroussin RETURN_ERROR("Few cols, width < size buttons or "\ 507c76f0793SBaptiste Daroussin "name+descripion of the items"); 508c76f0793SBaptiste Daroussin 509c76f0793SBaptiste Daroussin textrow = text != NULL && strlen(text) > 0 ? 1 : 0; 510c76f0793SBaptiste Daroussin 511c76f0793SBaptiste Daroussin if (nitems > 0 && menurows == 0) 512c76f0793SBaptiste Daroussin RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\ 513c76f0793SBaptiste Daroussin "too small"); 514c76f0793SBaptiste Daroussin 515c76f0793SBaptiste Daroussin menusize = nitems > 0 ? 3 : 0; 516c76f0793SBaptiste Daroussin if (rows < 2 + 2 + menusize + textrow) 517c76f0793SBaptiste Daroussin RETURN_ERROR("Few lines for this menus"); 518c76f0793SBaptiste Daroussin 519c76f0793SBaptiste Daroussin return 0; 520c76f0793SBaptiste Daroussin } 521c76f0793SBaptiste Daroussin 522c76f0793SBaptiste Daroussin /* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */ 523c76f0793SBaptiste Daroussin static void 524f499134dSBaptiste Daroussin update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w, 525c76f0793SBaptiste Daroussin int totnitems, unsigned int menurows, int ymenupad) 526c76f0793SBaptiste Daroussin { 527c76f0793SBaptiste Daroussin 528c76f0793SBaptiste Daroussin draw_borders(conf, menuwin, h, w, LOWERED); 529c76f0793SBaptiste Daroussin 5308c4f4028SBaptiste Daroussin if (totnitems > (int) menurows) { 531f499134dSBaptiste Daroussin wattron(menuwin, t.menu.arrowcolor); 532f499134dSBaptiste Daroussin 533f499134dSBaptiste Daroussin if (ymenupad > 0) 534f499134dSBaptiste Daroussin mvwprintw(menuwin, 0, 2, "^^^"); 535f499134dSBaptiste Daroussin 536f499134dSBaptiste Daroussin if ((int) (ymenupad + menurows) < totnitems) 537f499134dSBaptiste Daroussin mvwprintw(menuwin, h-1, 2, "vvv"); 538f499134dSBaptiste Daroussin 539f499134dSBaptiste Daroussin wattroff(menuwin, t.menu.arrowcolor); 540c76f0793SBaptiste Daroussin 541c76f0793SBaptiste Daroussin mvwprintw(menuwin, h-1, w-10, "%3d%%", 542c76f0793SBaptiste Daroussin 100 * (ymenupad + menurows) / totnitems); 543c76f0793SBaptiste Daroussin } 544c76f0793SBaptiste Daroussin } 545c76f0793SBaptiste Daroussin 546c76f0793SBaptiste Daroussin static int 547f499134dSBaptiste Daroussin do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols, 548c76f0793SBaptiste Daroussin unsigned int menurows, enum menumode mode, int ngroups, 549c76f0793SBaptiste Daroussin struct bsddialog_menugroup *groups, int *focuslist, int *focusitem) 550c76f0793SBaptiste Daroussin { 551c76f0793SBaptiste Daroussin WINDOW *shadow, *widget, *textpad, *menuwin, *menupad; 552c76f0793SBaptiste Daroussin int i, j, y, x, h, w, htextpad, output, input; 553c76f0793SBaptiste Daroussin int ymenupad, ys, ye, xs, xe, abs, g, rel, totnitems; 5548c4f4028SBaptiste Daroussin bool loop, automenurows, shortcut_buttons; 555c76f0793SBaptiste Daroussin struct buttons bs; 556c76f0793SBaptiste Daroussin struct bsddialog_menuitem *item; 557c76f0793SBaptiste Daroussin enum menumode currmode; 558c76f0793SBaptiste Daroussin struct lineposition pos = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 559c76f0793SBaptiste Daroussin 5608c4f4028SBaptiste Daroussin shortcut_buttons = conf->menu.shortcut_buttons; 5618c4f4028SBaptiste Daroussin 562c76f0793SBaptiste Daroussin automenurows = menurows == BSDDIALOG_AUTOSIZE ? true : false; 563c76f0793SBaptiste Daroussin 564c76f0793SBaptiste Daroussin totnitems = 0; 565c76f0793SBaptiste Daroussin for (i=0; i < ngroups; i++) { 566c76f0793SBaptiste Daroussin currmode = getmode(mode, groups[i]); 567c76f0793SBaptiste Daroussin if (currmode == RADIOLISTMODE) 568c76f0793SBaptiste Daroussin checkradiolist(groups[i].nitems, groups[i].items); 569c76f0793SBaptiste Daroussin 570c76f0793SBaptiste Daroussin if (currmode == MENUMODE) 571c76f0793SBaptiste Daroussin checkmenu(groups[i].nitems, groups[i].items); 572c76f0793SBaptiste Daroussin 573c76f0793SBaptiste Daroussin if (currmode == RADIOLISTMODE || currmode == CHECKLISTMODE) 574c76f0793SBaptiste Daroussin pos.selectorlen = 3; 575c76f0793SBaptiste Daroussin 576c76f0793SBaptiste Daroussin for (j=0; j < (int) groups[i].nitems; j++) { 577c76f0793SBaptiste Daroussin totnitems++; 578c76f0793SBaptiste Daroussin item = &groups[i].items[j]; 579c76f0793SBaptiste Daroussin 580c76f0793SBaptiste Daroussin if (groups[i].type == BSDDIALOG_SEPARATOR) { 581c76f0793SBaptiste Daroussin pos.maxsepstr = MAX(pos.maxsepstr, 582c76f0793SBaptiste Daroussin strlen(item->name) + strlen(item->desc)); 583c76f0793SBaptiste Daroussin continue; 584c76f0793SBaptiste Daroussin } 585c76f0793SBaptiste Daroussin 586c76f0793SBaptiste Daroussin pos.maxprefix = MAX(pos.maxprefix, strlen(item->prefix)); 5878c4f4028SBaptiste Daroussin pos.maxdepth = MAX(pos.maxdepth, item->depth); 588c76f0793SBaptiste Daroussin pos.maxname = MAX(pos.maxname, strlen(item->name)); 589c76f0793SBaptiste Daroussin pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc)); 590c76f0793SBaptiste Daroussin } 591c76f0793SBaptiste Daroussin } 592f499134dSBaptiste Daroussin pos.maxname = conf->menu.no_name ? 0 : pos.maxname; 593f499134dSBaptiste Daroussin pos.maxdesc = conf->menu.no_desc ? 0 : pos.maxdesc; 594c76f0793SBaptiste Daroussin pos.maxdepth *= DEPTHSPACE; 595c76f0793SBaptiste Daroussin 596c76f0793SBaptiste Daroussin pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0); 597c76f0793SBaptiste Daroussin pos.xname = pos.xselector + pos.selectorlen + (pos.selectorlen > 0 ? 1 : 0); 598c76f0793SBaptiste Daroussin pos.xdesc = pos.maxdepth + pos.xname + pos.maxname; 599c76f0793SBaptiste Daroussin pos.xdesc += (pos.maxname != 0 ? 1 : 0); 600c76f0793SBaptiste Daroussin pos.line = MAX(pos.maxsepstr + 3, pos.xdesc + pos.maxdesc); 601c76f0793SBaptiste Daroussin 602c76f0793SBaptiste Daroussin 603c76f0793SBaptiste Daroussin get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), 604c76f0793SBaptiste Daroussin BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); 605c76f0793SBaptiste Daroussin 606c76f0793SBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 607c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 608c76f0793SBaptiste Daroussin menu_autosize(conf, rows, cols, &h, &w, text, pos.line, &menurows, 609c76f0793SBaptiste Daroussin totnitems, bs); 610c76f0793SBaptiste Daroussin if (menu_checksize(h, w, text, menurows, totnitems, bs) != 0) 611c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 612c76f0793SBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 613c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 614c76f0793SBaptiste Daroussin 615c76f0793SBaptiste Daroussin if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, 616c76f0793SBaptiste Daroussin &textpad, &htextpad, text, true) != 0) 617c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 618c76f0793SBaptiste Daroussin 619f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, 620f499134dSBaptiste Daroussin y + h - menurows, x + 1 + w - t.text.hmargin); 621c76f0793SBaptiste Daroussin 622c76f0793SBaptiste Daroussin menuwin = new_boxed_window(conf, y + h - 5 - menurows, x + 2, 623c76f0793SBaptiste Daroussin menurows+2, w-4, LOWERED); 624c76f0793SBaptiste Daroussin 625c76f0793SBaptiste Daroussin menupad = newpad(totnitems, pos.line); 6268c4f4028SBaptiste Daroussin wbkgd(menupad, t.dialog.color); 627c76f0793SBaptiste Daroussin 628c76f0793SBaptiste Daroussin ymenupad = 0; 629c76f0793SBaptiste Daroussin for (i=0; i<ngroups; i++) { 630c76f0793SBaptiste Daroussin currmode = getmode(mode, groups[i]); 631c76f0793SBaptiste Daroussin for (j=0; j < (int) groups[i].nitems; j++) { 632c76f0793SBaptiste Daroussin item = &groups[i].items[j]; 6338c4f4028SBaptiste Daroussin drawitem(conf, menupad, ymenupad, *item, currmode, pos, 6348c4f4028SBaptiste Daroussin false); 635c76f0793SBaptiste Daroussin ymenupad++; 636c76f0793SBaptiste Daroussin } 637c76f0793SBaptiste Daroussin } 6388c4f4028SBaptiste Daroussin getfirst_with_default(conf, ngroups, groups, &abs, &g, &rel); 6398c4f4028SBaptiste Daroussin currmode = getmode(mode, groups[g]); 6408c4f4028SBaptiste Daroussin item = &groups[g].items[rel]; 6418c4f4028SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, true); 642c76f0793SBaptiste Daroussin 643c76f0793SBaptiste Daroussin ys = y + h - 5 - menurows + 1; 644c76f0793SBaptiste Daroussin ye = y + h - 5 ; 645f499134dSBaptiste Daroussin if (conf->menu.align_left || (int)pos.line > w - 6) { 646c76f0793SBaptiste Daroussin xs = x + 3; 647c76f0793SBaptiste Daroussin xe = xs + w - 7; 648c76f0793SBaptiste Daroussin } 649c76f0793SBaptiste Daroussin else { /* center */ 650c76f0793SBaptiste Daroussin xs = x + 3 + (w-6)/2 - pos.line/2; 651c76f0793SBaptiste Daroussin xe = xs + w - 5; 652c76f0793SBaptiste Daroussin } 653c76f0793SBaptiste Daroussin 654c76f0793SBaptiste Daroussin ymenupad = 0; /* now ymenupad is pminrow for prefresh() */ 655c76f0793SBaptiste Daroussin if ((int)(ymenupad + menurows) - 1 < abs) 656c76f0793SBaptiste Daroussin ymenupad = abs - menurows + 1; 657c76f0793SBaptiste Daroussin update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, menurows, ymenupad); 658c76f0793SBaptiste Daroussin wrefresh(menuwin); 659c76f0793SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 660c76f0793SBaptiste Daroussin 6618c4f4028SBaptiste Daroussin draw_buttons(widget, h-2, w, bs, shortcut_buttons); 662c76f0793SBaptiste Daroussin wrefresh(widget); 663c76f0793SBaptiste Daroussin 664c76f0793SBaptiste Daroussin loop = true; 665c76f0793SBaptiste Daroussin while(loop) { 666c76f0793SBaptiste Daroussin input = getch(); 667c76f0793SBaptiste Daroussin switch(input) { 668c76f0793SBaptiste Daroussin case KEY_ENTER: 669c76f0793SBaptiste Daroussin case 10: /* Enter */ 670c76f0793SBaptiste Daroussin output = bs.value[bs.curr]; 671c76f0793SBaptiste Daroussin if (currmode == MENUMODE) 672c76f0793SBaptiste Daroussin item->on = true; 673c76f0793SBaptiste Daroussin loop = false; 674c76f0793SBaptiste Daroussin break; 675c76f0793SBaptiste Daroussin case 27: /* Esc */ 676c76f0793SBaptiste Daroussin output = BSDDIALOG_ESC; 677c76f0793SBaptiste Daroussin loop = false; 678c76f0793SBaptiste Daroussin break; 679c76f0793SBaptiste Daroussin case '\t': /* TAB */ 680c76f0793SBaptiste Daroussin bs.curr = (bs.curr + 1) % bs.nbuttons; 6818c4f4028SBaptiste Daroussin draw_buttons(widget, h-2, w, bs, shortcut_buttons); 682c76f0793SBaptiste Daroussin wrefresh(widget); 683c76f0793SBaptiste Daroussin break; 684c76f0793SBaptiste Daroussin case KEY_LEFT: 685c76f0793SBaptiste Daroussin if (bs.curr > 0) { 686c76f0793SBaptiste Daroussin bs.curr--; 6878c4f4028SBaptiste Daroussin draw_buttons(widget, h-2, w, bs, shortcut_buttons); 688c76f0793SBaptiste Daroussin wrefresh(widget); 689c76f0793SBaptiste Daroussin } 690c76f0793SBaptiste Daroussin break; 691c76f0793SBaptiste Daroussin case KEY_RIGHT: 692c76f0793SBaptiste Daroussin if (bs.curr < (int) bs.nbuttons - 1) { 693c76f0793SBaptiste Daroussin bs.curr++; 6948c4f4028SBaptiste Daroussin draw_buttons(widget, h-2, w, bs, shortcut_buttons); 695c76f0793SBaptiste Daroussin wrefresh(widget); 696c76f0793SBaptiste Daroussin } 697c76f0793SBaptiste Daroussin break; 698f499134dSBaptiste Daroussin case KEY_CTRL('E'): /* add conf->menu.extrahelpkey ? */ 699c76f0793SBaptiste Daroussin case KEY_F(1): 7008c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 701c76f0793SBaptiste Daroussin break; 702c76f0793SBaptiste Daroussin if (f1help(conf) != 0) 703c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 704c76f0793SBaptiste Daroussin /* No break! the terminal size can change */ 705c76f0793SBaptiste Daroussin case KEY_RESIZE: 706f499134dSBaptiste Daroussin hide_widget(y, x, h, w,conf->shadow); 707c76f0793SBaptiste Daroussin 708c76f0793SBaptiste Daroussin /* 709c76f0793SBaptiste Daroussin * Unnecessary, but, when the columns decrease the 710c76f0793SBaptiste Daroussin * following "refresh" seem not work 711c76f0793SBaptiste Daroussin */ 712c76f0793SBaptiste Daroussin refresh(); 713c76f0793SBaptiste Daroussin 714c76f0793SBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 715c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 716c76f0793SBaptiste Daroussin menurows = automenurows ? 0 : menurows; 717c76f0793SBaptiste Daroussin menu_autosize(conf, rows, cols, &h, &w, text, pos.line, 718c76f0793SBaptiste Daroussin &menurows, totnitems, bs); 719c76f0793SBaptiste Daroussin if (menu_checksize(h, w, text, menurows, totnitems, bs) != 0) 720c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 721c76f0793SBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 722c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 723c76f0793SBaptiste Daroussin 724c76f0793SBaptiste Daroussin wclear(shadow); 725f499134dSBaptiste Daroussin mvwin(shadow, y + t.shadow.h, x + t.shadow.w); 726c76f0793SBaptiste Daroussin wresize(shadow, h, w); 727c76f0793SBaptiste Daroussin 728c76f0793SBaptiste Daroussin wclear(widget); 729c76f0793SBaptiste Daroussin mvwin(widget, y, x); 730c76f0793SBaptiste Daroussin wresize(widget, h, w); 731c76f0793SBaptiste Daroussin 732c76f0793SBaptiste Daroussin htextpad = 1; 733c76f0793SBaptiste Daroussin wclear(textpad); 734f499134dSBaptiste Daroussin wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); 735c76f0793SBaptiste Daroussin 736c76f0793SBaptiste Daroussin if(update_widget_withtextpad(conf, shadow, widget, h, w, 737c76f0793SBaptiste Daroussin RAISED, textpad, &htextpad, text, true) != 0) 738c76f0793SBaptiste Daroussin return BSDDIALOG_ERROR; 739c76f0793SBaptiste Daroussin 7408c4f4028SBaptiste Daroussin draw_buttons(widget, h-2, w, bs, shortcut_buttons); 741c76f0793SBaptiste Daroussin wrefresh(widget); 742c76f0793SBaptiste Daroussin 743f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, 744f499134dSBaptiste Daroussin y + h - menurows, x + 1 + w - t.text.hmargin); 745c76f0793SBaptiste Daroussin 746c76f0793SBaptiste Daroussin wclear(menuwin); 747c76f0793SBaptiste Daroussin mvwin(menuwin, y + h - 5 - menurows, x + 2); 748c76f0793SBaptiste Daroussin wresize(menuwin,menurows+2, w-4); 749c76f0793SBaptiste Daroussin update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, 750c76f0793SBaptiste Daroussin menurows, ymenupad); 751c76f0793SBaptiste Daroussin wrefresh(menuwin); 752c76f0793SBaptiste Daroussin 753c76f0793SBaptiste Daroussin ys = y + h - 5 - menurows + 1; 754c76f0793SBaptiste Daroussin ye = y + h - 5 ; 755f499134dSBaptiste Daroussin if (conf->menu.align_left || (int)pos.line > w - 6) { 756c76f0793SBaptiste Daroussin xs = x + 3; 757c76f0793SBaptiste Daroussin xe = xs + w - 7; 758c76f0793SBaptiste Daroussin } 759c76f0793SBaptiste Daroussin else { /* center */ 760c76f0793SBaptiste Daroussin xs = x + 3 + (w-6)/2 - pos.line/2; 761c76f0793SBaptiste Daroussin xe = xs + w - 5; 762c76f0793SBaptiste Daroussin } 763c76f0793SBaptiste Daroussin 764c76f0793SBaptiste Daroussin if ((int)(ymenupad + menurows) - 1 < abs) 765c76f0793SBaptiste Daroussin ymenupad = abs - menurows + 1; 766c76f0793SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 767c76f0793SBaptiste Daroussin 768c76f0793SBaptiste Daroussin refresh(); 769c76f0793SBaptiste Daroussin 770c76f0793SBaptiste Daroussin break; 771c76f0793SBaptiste Daroussin } 772c76f0793SBaptiste Daroussin 773c76f0793SBaptiste Daroussin if (abs < 0) 774c76f0793SBaptiste Daroussin continue; 775c76f0793SBaptiste Daroussin switch(input) { 776c76f0793SBaptiste Daroussin case KEY_HOME: 777c76f0793SBaptiste Daroussin case KEY_UP: 778c76f0793SBaptiste Daroussin case KEY_PPAGE: 779c76f0793SBaptiste Daroussin if (abs == 0) /* useless, just to save cpu refresh */ 780c76f0793SBaptiste Daroussin break; 781c76f0793SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, false); 782c76f0793SBaptiste Daroussin if (input == KEY_HOME) 783c76f0793SBaptiste Daroussin getfirst(ngroups, groups, &abs, &g, &rel); 784c76f0793SBaptiste Daroussin else if (input == KEY_UP) 785c76f0793SBaptiste Daroussin getprev(groups, &abs, &g, &rel); 786c76f0793SBaptiste Daroussin else /* input == KEY_PPAGE*/ 787c76f0793SBaptiste Daroussin getfastprev(menurows, groups, &abs, &g, &rel); 788c76f0793SBaptiste Daroussin item = &groups[g].items[rel]; 789c76f0793SBaptiste Daroussin currmode= getmode(mode, groups[g]); 790c76f0793SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, true); 791c76f0793SBaptiste Daroussin if (ymenupad > abs && ymenupad > 0) 792c76f0793SBaptiste Daroussin ymenupad = abs; 793c76f0793SBaptiste Daroussin update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, 794c76f0793SBaptiste Daroussin menurows, ymenupad); 795c76f0793SBaptiste Daroussin wrefresh(menuwin); 796c76f0793SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 797c76f0793SBaptiste Daroussin break; 798c76f0793SBaptiste Daroussin case KEY_END: 799c76f0793SBaptiste Daroussin case KEY_DOWN: 800c76f0793SBaptiste Daroussin case KEY_NPAGE: 801c76f0793SBaptiste Daroussin if (abs == totnitems -1) 802c76f0793SBaptiste Daroussin break; /* useless, just to save cpu refresh */ 803c76f0793SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, false); 804c76f0793SBaptiste Daroussin if (input == KEY_END) 805c76f0793SBaptiste Daroussin getlast(totnitems, ngroups, groups, &abs, &g, &rel); 806c76f0793SBaptiste Daroussin else if (input == KEY_DOWN) 807c76f0793SBaptiste Daroussin getnext(ngroups, groups, &abs, &g, &rel); 808c76f0793SBaptiste Daroussin else /* input == KEY_NPAGE*/ 809c76f0793SBaptiste Daroussin getfastnext(menurows, ngroups, groups, &abs, &g, &rel); 810c76f0793SBaptiste Daroussin item = &groups[g].items[rel]; 811c76f0793SBaptiste Daroussin currmode= getmode(mode, groups[g]); 812c76f0793SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, true); 813c76f0793SBaptiste Daroussin if ((int)(ymenupad + menurows) <= abs) 814c76f0793SBaptiste Daroussin ymenupad = abs - menurows + 1; 815c76f0793SBaptiste Daroussin update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, 816c76f0793SBaptiste Daroussin menurows, ymenupad); 817c76f0793SBaptiste Daroussin wrefresh(menuwin); 818c76f0793SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 819c76f0793SBaptiste Daroussin break; 820c76f0793SBaptiste Daroussin case ' ': /* Space */ 821c76f0793SBaptiste Daroussin if (currmode == MENUMODE) 822c76f0793SBaptiste Daroussin break; 823c76f0793SBaptiste Daroussin else if (currmode == CHECKLISTMODE) 824c76f0793SBaptiste Daroussin item->on = !item->on; 825c76f0793SBaptiste Daroussin else { /* RADIOLISTMODE */ 826c76f0793SBaptiste Daroussin for (i=0; i < (int) groups[g].nitems; i++) 827f499134dSBaptiste Daroussin if (groups[g].items[i].on == true && i != rel) { 828c76f0793SBaptiste Daroussin groups[g].items[i].on = false; 829c76f0793SBaptiste Daroussin drawitem(conf, menupad, 830c76f0793SBaptiste Daroussin abs - rel + i, groups[g].items[i], 831c76f0793SBaptiste Daroussin currmode, pos, false); 832c76f0793SBaptiste Daroussin } 833f499134dSBaptiste Daroussin item->on = !item->on; 834c76f0793SBaptiste Daroussin } 835c76f0793SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, true); 836c76f0793SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 8378c4f4028SBaptiste Daroussin default: 8388c4f4028SBaptiste Daroussin if (shortcut_buttons) { 8398c4f4028SBaptiste Daroussin for (i = 0; i < (int) bs.nbuttons; i++) 8408c4f4028SBaptiste Daroussin if (tolower(input) == tolower((bs.label[i])[0])) { 8418c4f4028SBaptiste Daroussin output = bs.value[i]; 8428c4f4028SBaptiste Daroussin if (currmode == MENUMODE) 8438c4f4028SBaptiste Daroussin item->on = true; 8448c4f4028SBaptiste Daroussin loop = false; 8458c4f4028SBaptiste Daroussin } 8468c4f4028SBaptiste Daroussin break; 8478c4f4028SBaptiste Daroussin } 8488c4f4028SBaptiste Daroussin 8498c4f4028SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, false); 8508c4f4028SBaptiste Daroussin getnextshortcut(conf, currmode, ngroups, groups, &abs, 8518c4f4028SBaptiste Daroussin &g, &rel, input); 8528c4f4028SBaptiste Daroussin item = &groups[g].items[rel]; 8538c4f4028SBaptiste Daroussin currmode = getmode(mode, groups[g]); 8548c4f4028SBaptiste Daroussin drawitem(conf, menupad, abs, *item, currmode, pos, true); 8558c4f4028SBaptiste Daroussin if (ymenupad > abs && ymenupad > 0) 8568c4f4028SBaptiste Daroussin ymenupad = abs; 8578c4f4028SBaptiste Daroussin if ((int)(ymenupad + menurows) <= abs) 8588c4f4028SBaptiste Daroussin ymenupad = abs - menurows + 1; 8598c4f4028SBaptiste Daroussin update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, 8608c4f4028SBaptiste Daroussin menurows, ymenupad); 8618c4f4028SBaptiste Daroussin wrefresh(menuwin); 8628c4f4028SBaptiste Daroussin prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); 863c76f0793SBaptiste Daroussin } 864c76f0793SBaptiste Daroussin } 865c76f0793SBaptiste Daroussin 866c76f0793SBaptiste Daroussin if (focuslist != NULL) 867c76f0793SBaptiste Daroussin *focuslist = g; 868c76f0793SBaptiste Daroussin if (focusitem !=NULL) 869c76f0793SBaptiste Daroussin *focusitem = rel; 870c76f0793SBaptiste Daroussin 871c76f0793SBaptiste Daroussin delwin(menupad); 872c76f0793SBaptiste Daroussin delwin(menuwin); 873c76f0793SBaptiste Daroussin end_widget_withtextpad(conf, widget, h, w, textpad, shadow); 874c76f0793SBaptiste Daroussin 875c76f0793SBaptiste Daroussin return output; 876c76f0793SBaptiste Daroussin } 877c76f0793SBaptiste Daroussin 878c76f0793SBaptiste Daroussin /* 879c76f0793SBaptiste Daroussin * API 880c76f0793SBaptiste Daroussin */ 881c76f0793SBaptiste Daroussin 882f499134dSBaptiste Daroussin int bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols, 883c76f0793SBaptiste Daroussin unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups, 884c76f0793SBaptiste Daroussin int *focuslist, int *focusitem) 885c76f0793SBaptiste Daroussin { 886c76f0793SBaptiste Daroussin int output; 887c76f0793SBaptiste Daroussin 888c76f0793SBaptiste Daroussin output = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE, 889c76f0793SBaptiste Daroussin ngroups, groups, focuslist, focusitem); 890c76f0793SBaptiste Daroussin 891c76f0793SBaptiste Daroussin return output; 892c76f0793SBaptiste Daroussin } 893c76f0793SBaptiste Daroussin 894c76f0793SBaptiste Daroussin int 895f499134dSBaptiste Daroussin bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols, 896c76f0793SBaptiste Daroussin unsigned int menurows, int nitems, struct bsddialog_menuitem *items, 897c76f0793SBaptiste Daroussin int *focusitem) 898c76f0793SBaptiste Daroussin { 899c76f0793SBaptiste Daroussin int output; 900c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 901c76f0793SBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items}; 902c76f0793SBaptiste Daroussin 903c76f0793SBaptiste Daroussin output = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE, 904c76f0793SBaptiste Daroussin 1, &group, NULL, focusitem); 905c76f0793SBaptiste Daroussin 906c76f0793SBaptiste Daroussin return output; 907c76f0793SBaptiste Daroussin } 908c76f0793SBaptiste Daroussin 909c76f0793SBaptiste Daroussin int 910f499134dSBaptiste Daroussin bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols, 911c76f0793SBaptiste Daroussin unsigned int menurows, int nitems, struct bsddialog_menuitem *items, 912c76f0793SBaptiste Daroussin int *focusitem) 913c76f0793SBaptiste Daroussin { 914c76f0793SBaptiste Daroussin int output; 915c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 916c76f0793SBaptiste Daroussin BSDDIALOG_CHECKLIST /* unused */, nitems, items}; 917c76f0793SBaptiste Daroussin 918c76f0793SBaptiste Daroussin output = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1, 919c76f0793SBaptiste Daroussin &group, NULL, focusitem); 920c76f0793SBaptiste Daroussin 921c76f0793SBaptiste Daroussin return output; 922c76f0793SBaptiste Daroussin } 923c76f0793SBaptiste Daroussin 924c76f0793SBaptiste Daroussin int 925f499134dSBaptiste Daroussin bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols, 926c76f0793SBaptiste Daroussin unsigned int menurows, int nitems, struct bsddialog_menuitem *items, 927c76f0793SBaptiste Daroussin int *focusitem) 928c76f0793SBaptiste Daroussin { 929c76f0793SBaptiste Daroussin int output; 930c76f0793SBaptiste Daroussin struct bsddialog_menugroup group = { 931c76f0793SBaptiste Daroussin BSDDIALOG_RADIOLIST /* unused */, nitems, items}; 932c76f0793SBaptiste Daroussin 933c76f0793SBaptiste Daroussin output = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE, 934c76f0793SBaptiste Daroussin 1, &group, NULL, focusitem); 935c76f0793SBaptiste Daroussin 936c76f0793SBaptiste Daroussin return output; 937c76f0793SBaptiste Daroussin } 938c76f0793SBaptiste Daroussin 939f499134dSBaptiste Daroussin /* todo */ 940f499134dSBaptiste Daroussin static int buildlist_autosize(int rows, int cols) 941c76f0793SBaptiste Daroussin { 942c76f0793SBaptiste Daroussin 943f499134dSBaptiste Daroussin if (cols == BSDDIALOG_AUTOSIZE) 944f499134dSBaptiste Daroussin RETURN_ERROR("Unimplemented cols autosize for buildlist"); 945c76f0793SBaptiste Daroussin 946f499134dSBaptiste Daroussin if (rows == BSDDIALOG_AUTOSIZE) 947f499134dSBaptiste Daroussin RETURN_ERROR("Unimplemented rows autosize for buildlist"); 948c76f0793SBaptiste Daroussin 949f499134dSBaptiste Daroussin return 0; 950f499134dSBaptiste Daroussin } 951f499134dSBaptiste Daroussin 952f499134dSBaptiste Daroussin /* to improve */ 953f499134dSBaptiste Daroussin static int 954f499134dSBaptiste Daroussin buildlist_checksize(int rows, int cols, char *text, int menurows, int nitems, 955f499134dSBaptiste Daroussin struct buttons bs) 956f499134dSBaptiste Daroussin { 957f499134dSBaptiste Daroussin int mincols, textrow, menusize; 958f499134dSBaptiste Daroussin 959f499134dSBaptiste Daroussin mincols = VBORDERS; 960f499134dSBaptiste Daroussin /* buttons */ 961f499134dSBaptiste Daroussin mincols += bs.nbuttons * bs.sizebutton; 962f499134dSBaptiste Daroussin mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 963f499134dSBaptiste Daroussin /* line, comment to permet some cols hidden */ 964f499134dSBaptiste Daroussin /* mincols = MAX(mincols, linelen); */ 965f499134dSBaptiste Daroussin 966f499134dSBaptiste Daroussin if (cols < mincols) 967f499134dSBaptiste Daroussin RETURN_ERROR("Few cols, width < size buttons or "\ 968f499134dSBaptiste Daroussin "name+descripion of the items"); 969f499134dSBaptiste Daroussin 970f499134dSBaptiste Daroussin textrow = text != NULL && strlen(text) > 0 ? 1 : 0; 971f499134dSBaptiste Daroussin 972f499134dSBaptiste Daroussin if (nitems > 0 && menurows == 0) 973f499134dSBaptiste Daroussin RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\ 974f499134dSBaptiste Daroussin "too small"); 975f499134dSBaptiste Daroussin 976f499134dSBaptiste Daroussin menusize = nitems > 0 ? 3 : 0; 977f499134dSBaptiste Daroussin if (rows < 2 + 2 + menusize + textrow) 978f499134dSBaptiste Daroussin RETURN_ERROR("Few lines for this menus"); 979f499134dSBaptiste Daroussin 980f499134dSBaptiste Daroussin return 0; 981c76f0793SBaptiste Daroussin } 982c76f0793SBaptiste Daroussin 983c76f0793SBaptiste Daroussin int 984f499134dSBaptiste Daroussin bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols, 985c76f0793SBaptiste Daroussin unsigned int menurows, int nitems, struct bsddialog_menuitem *items, 986c76f0793SBaptiste Daroussin int *focusitem) 987c76f0793SBaptiste Daroussin { 988f499134dSBaptiste Daroussin WINDOW *widget, *textpad, *leftwin, *leftpad, *rightwin, *rightpad, *shadow; 989f499134dSBaptiste Daroussin int output, i, x, y, h, w, htextpad, input; 990c76f0793SBaptiste Daroussin bool loop, buttupdate, padsupdate, startleft; 991c76f0793SBaptiste Daroussin int nlefts, nrights, leftwinx, rightwinx, winsy, padscols, curr; 992c76f0793SBaptiste Daroussin enum side {LEFT, RIGHT} currV; 993c76f0793SBaptiste Daroussin int currH; 994c76f0793SBaptiste Daroussin struct buttons bs; 995c76f0793SBaptiste Daroussin struct lineposition pos = {0,0,0,0,0,0,0,0,0,0}; 996c76f0793SBaptiste Daroussin 997c76f0793SBaptiste Daroussin startleft = false; 998c76f0793SBaptiste Daroussin for (i=0; i<nitems; i++) { 999c76f0793SBaptiste Daroussin pos.line = MAX(pos.line, strlen(items[i].desc)); 1000c76f0793SBaptiste Daroussin if (items[i].on == false) 1001c76f0793SBaptiste Daroussin startleft = true; 1002c76f0793SBaptiste Daroussin } 1003c76f0793SBaptiste Daroussin 1004f499134dSBaptiste Daroussin get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), 1005f499134dSBaptiste Daroussin BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); 1006c76f0793SBaptiste Daroussin 1007f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 1008f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 1009f499134dSBaptiste Daroussin if (buildlist_autosize(rows, cols) != 0) 1010f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 1011f499134dSBaptiste Daroussin if (buildlist_checksize(h, w, text, menurows, nitems, bs) != 0) 1012f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 1013f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 1014f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 1015f499134dSBaptiste Daroussin 1016f499134dSBaptiste Daroussin if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, 1017f499134dSBaptiste Daroussin &textpad, &htextpad, text, true) != 0) 1018f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 1019f499134dSBaptiste Daroussin 1020f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin, 1021f499134dSBaptiste Daroussin y + h - menurows, x + 1 + w - t.text.hmargin); 1022f499134dSBaptiste Daroussin 1023f499134dSBaptiste Daroussin winsy = y + h - 5 - menurows; 1024c76f0793SBaptiste Daroussin leftwinx = x+2; 1025f499134dSBaptiste Daroussin leftwin = new_boxed_window(conf, winsy, leftwinx, menurows+2, (w-5)/2, 1026c76f0793SBaptiste Daroussin LOWERED); 1027f499134dSBaptiste Daroussin rightwinx = x + w - 2 -(w-5)/2; 1028c76f0793SBaptiste Daroussin rightwin = new_boxed_window(conf, winsy, rightwinx, menurows+2, 1029f499134dSBaptiste Daroussin (w-5)/2, LOWERED); 1030c76f0793SBaptiste Daroussin 1031c76f0793SBaptiste Daroussin wrefresh(leftwin); 1032c76f0793SBaptiste Daroussin wrefresh(rightwin); 1033c76f0793SBaptiste Daroussin 1034f499134dSBaptiste Daroussin padscols = (w-5)/2 - 2; 1035c76f0793SBaptiste Daroussin leftpad = newpad(nitems, pos.line); 1036c76f0793SBaptiste Daroussin rightpad = newpad(nitems, pos.line); 10378c4f4028SBaptiste Daroussin wbkgd(leftpad, t.dialog.color); 10388c4f4028SBaptiste Daroussin wbkgd(rightpad, t.dialog.color); 1039c76f0793SBaptiste Daroussin 1040c76f0793SBaptiste Daroussin currH = 0; 1041c76f0793SBaptiste Daroussin currV = startleft ? LEFT : RIGHT; 1042c76f0793SBaptiste Daroussin loop = buttupdate = padsupdate = true; 1043c76f0793SBaptiste Daroussin while(loop) { 1044c76f0793SBaptiste Daroussin if (buttupdate) { 1045f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 1046c76f0793SBaptiste Daroussin wrefresh(widget); 1047c76f0793SBaptiste Daroussin buttupdate = false; 1048c76f0793SBaptiste Daroussin } 1049c76f0793SBaptiste Daroussin 1050c76f0793SBaptiste Daroussin if (padsupdate) { 1051c76f0793SBaptiste Daroussin werase(leftpad); 1052c76f0793SBaptiste Daroussin werase(rightpad); 1053c76f0793SBaptiste Daroussin curr = -1; 1054c76f0793SBaptiste Daroussin nlefts = nrights = 0; 1055c76f0793SBaptiste Daroussin for (i=0; i<nitems; i++) { 1056c76f0793SBaptiste Daroussin if (items[i].on == false) { 1057c76f0793SBaptiste Daroussin if (currV == LEFT && currH == nlefts) 1058c76f0793SBaptiste Daroussin curr = i; 1059c76f0793SBaptiste Daroussin drawitem(conf, leftpad, nlefts, items[i], 1060c76f0793SBaptiste Daroussin BUILDLISTMODE, pos, curr == i); 1061c76f0793SBaptiste Daroussin nlefts++; 1062c76f0793SBaptiste Daroussin } else { 1063c76f0793SBaptiste Daroussin if (currV == RIGHT && currH == nrights) 1064c76f0793SBaptiste Daroussin curr = i; 1065c76f0793SBaptiste Daroussin drawitem(conf, rightpad, nrights, items[i], 1066c76f0793SBaptiste Daroussin BUILDLISTMODE, pos, curr == i); 1067c76f0793SBaptiste Daroussin nrights++; 1068c76f0793SBaptiste Daroussin } 1069c76f0793SBaptiste Daroussin } 1070c76f0793SBaptiste Daroussin prefresh(leftpad, 0, 0, winsy+1, leftwinx+1, 1071c76f0793SBaptiste Daroussin winsy+1+menurows, leftwinx + 1 + padscols); 1072c76f0793SBaptiste Daroussin prefresh(rightpad, 0, 0, winsy+1, rightwinx+1, 1073c76f0793SBaptiste Daroussin winsy+1+menurows, rightwinx + 1 + padscols); 1074c76f0793SBaptiste Daroussin padsupdate = false; 1075c76f0793SBaptiste Daroussin } 1076c76f0793SBaptiste Daroussin 1077c76f0793SBaptiste Daroussin input = getch(); 1078c76f0793SBaptiste Daroussin switch(input) { 1079f499134dSBaptiste Daroussin case KEY_ENTER: 1080f499134dSBaptiste Daroussin case 10: /* Enter */ 1081f499134dSBaptiste Daroussin output = bs.value[bs.curr]; 1082c76f0793SBaptiste Daroussin loop = false; 1083c76f0793SBaptiste Daroussin break; 1084f499134dSBaptiste Daroussin case 27: /* Esc */ 1085c76f0793SBaptiste Daroussin output = BSDDIALOG_ERROR; 1086c76f0793SBaptiste Daroussin loop = false; 1087c76f0793SBaptiste Daroussin break; 1088f499134dSBaptiste Daroussin case '\t': /* TAB */ 1089c76f0793SBaptiste Daroussin bs.curr = (bs.curr + 1) % bs.nbuttons; 1090c76f0793SBaptiste Daroussin buttupdate = true; 1091c76f0793SBaptiste Daroussin break; 1092c76f0793SBaptiste Daroussin } 1093c76f0793SBaptiste Daroussin 1094c76f0793SBaptiste Daroussin if (nitems <= 0) 1095c76f0793SBaptiste Daroussin continue; 1096c76f0793SBaptiste Daroussin 1097c76f0793SBaptiste Daroussin switch(input) { 1098c76f0793SBaptiste Daroussin case KEY_LEFT: 1099c76f0793SBaptiste Daroussin if (currV == RIGHT && nrights > 0) { 1100c76f0793SBaptiste Daroussin currV = LEFT; 1101c76f0793SBaptiste Daroussin currH = 0; 1102c76f0793SBaptiste Daroussin padsupdate = true; 1103c76f0793SBaptiste Daroussin } 1104c76f0793SBaptiste Daroussin break; 1105c76f0793SBaptiste Daroussin case KEY_RIGHT: 1106c76f0793SBaptiste Daroussin if (currV == LEFT && nrights > 0) { 1107c76f0793SBaptiste Daroussin currV = RIGHT; 1108c76f0793SBaptiste Daroussin currH = 0; 1109c76f0793SBaptiste Daroussin padsupdate = true; 1110c76f0793SBaptiste Daroussin } 1111c76f0793SBaptiste Daroussin break; 1112c76f0793SBaptiste Daroussin case KEY_UP: 1113c76f0793SBaptiste Daroussin currH = (currH > 0) ? currH - 1 : 0; 1114c76f0793SBaptiste Daroussin padsupdate = true; 1115c76f0793SBaptiste Daroussin break; 1116c76f0793SBaptiste Daroussin case KEY_DOWN: 1117c76f0793SBaptiste Daroussin if (currV == LEFT) 1118c76f0793SBaptiste Daroussin currH = (currH < nlefts-1) ? currH +1 : currH; 1119c76f0793SBaptiste Daroussin else 1120c76f0793SBaptiste Daroussin currH = (currH < nrights-1)? currH +1 : currH; 1121c76f0793SBaptiste Daroussin padsupdate = true; 1122c76f0793SBaptiste Daroussin break; 1123f499134dSBaptiste Daroussin case ' ': /* Space */ 1124c76f0793SBaptiste Daroussin items[curr].on = ! items[curr].on; 1125c76f0793SBaptiste Daroussin if (currV == LEFT) { 1126c76f0793SBaptiste Daroussin if (nlefts > 1) 1127c76f0793SBaptiste Daroussin currH = currH > 0 ? currH-1 : 0; 1128c76f0793SBaptiste Daroussin else { 1129c76f0793SBaptiste Daroussin currH = 0; 1130c76f0793SBaptiste Daroussin currV = RIGHT; 1131c76f0793SBaptiste Daroussin } 1132c76f0793SBaptiste Daroussin } else { 1133c76f0793SBaptiste Daroussin if (nrights > 1) 1134c76f0793SBaptiste Daroussin currH = currH > 0 ? currH-1 : 0; 1135c76f0793SBaptiste Daroussin else { 1136c76f0793SBaptiste Daroussin currH = 0; 1137c76f0793SBaptiste Daroussin currV = LEFT; 1138c76f0793SBaptiste Daroussin } 1139c76f0793SBaptiste Daroussin } 1140c76f0793SBaptiste Daroussin padsupdate = true; 1141c76f0793SBaptiste Daroussin break; 1142c76f0793SBaptiste Daroussin default: 1143c76f0793SBaptiste Daroussin 1144c76f0793SBaptiste Daroussin break; 1145c76f0793SBaptiste Daroussin } 1146c76f0793SBaptiste Daroussin } 1147c76f0793SBaptiste Daroussin 1148c76f0793SBaptiste Daroussin if(focusitem != NULL) 1149c76f0793SBaptiste Daroussin *focusitem = curr; 1150c76f0793SBaptiste Daroussin 1151c76f0793SBaptiste Daroussin delwin(leftpad); 1152c76f0793SBaptiste Daroussin delwin(leftwin); 1153c76f0793SBaptiste Daroussin delwin(rightpad); 1154c76f0793SBaptiste Daroussin delwin(rightwin); 1155f499134dSBaptiste Daroussin end_widget_withtextpad(conf, widget, h, w, textpad, shadow); 1156c76f0793SBaptiste Daroussin 1157c76f0793SBaptiste Daroussin return output; 1158c76f0793SBaptiste Daroussin } 1159