/* * wavemon - a wireless network monitoring aplication * * Copyright (c) 2001-2002 Jan Morgenstern * * wavemon is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2, or (at your option) any later * version. * * wavemon is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with wavemon; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "wavemon.h" /* Make configuration screen fit into half of minimum screen width */ #define CONF_SCREEN_WIDTH (MIN_SCREEN_COLS / 2) /* * Maximum number of rows in the configuration box. Due to the top * border, this is one less than the maximum vertical number of rows. */ #define MAX_NUM_CONF_ROWS (MAXYLEN - 1) /* GLOBALS */ extern int conf_items; /* index into array storing menu items */ static WINDOW *w_conf, *w_confpad; static int first_item, active_item; static int num_items, list_offset; static void waddstr_item(WINDOW *w, int y, struct conf_item *item, char hilight) { char s[0x40]; wattrset(w, COLOR_PAIR(CP_PREF_NORMAL)); mvwhline(w, y, 0, ' ', CONF_SCREEN_WIDTH); if (item->type != t_sep && item->type != t_func) { mvwaddstr(w, y, item->dep ? 2 : 0, item->name); switch (item->type) { case t_int: sprintf(s, "%d", *item->v.i); break; case t_list: assert(item->list && item->list[*item->v.i]); strncpy(s, item->list[*item->v.i], sizeof(s)-1); /* Fall through, dummy statements to pacify gcc -Wall */ case t_sep: case t_func: break; } if (!item->unit) { wmove(w, y, CONF_SCREEN_WIDTH - strlen(s)); if (hilight) { wattron(w, A_REVERSE); waddstr_b(w, s); wattroff(w, A_REVERSE); } else waddstr_b(w, s); } else { wmove(w, y, CONF_SCREEN_WIDTH - strlen(s) - strlen(item->unit) - 1); if (hilight) { wattron(w, A_REVERSE); waddstr_b(w, s); wattroff(w, A_REVERSE); } else waddstr_b(w, s); mvwaddstr(w, y, CONF_SCREEN_WIDTH - strlen(item->unit), item->unit); } } else if (item->type == t_sep && item->name) { sprintf(s, "- %s -", item->name); mvwaddstr(w, y, (CONF_SCREEN_WIDTH - strlen(s)) / 2, s); } else if (item->type == t_func) { wmove(w, y, (CONF_SCREEN_WIDTH - strlen(item->name)) / 2); if (hilight) { wattron(w, A_REVERSE); waddstr(w, item->name); wattroff(w, A_REVERSE); } else waddstr(w, item->name); } } static void change_item(int inum, int sign) { struct conf_item *item = ll_get(conf_items, inum); int tmp; switch (item->type) { case t_int: if (*item->v.i + item->inc * sign <= item->max && *item->v.i + item->inc * sign >= item->min) *item->v.i += item->inc * sign; break; case t_list: *item->v.i = *item->v.i + sign; tmp = argv_count(item->list); if (*item->v.i >= tmp) *item->v.i = 0; else if (*item->v.i < 0) *item->v.i = tmp - 1; /* Fall through, dummy statements to pacify gcc -Wall */ case t_sep: case t_func: break; } } static int select_item(int rv, int incr) { struct conf_item *item; do { rv += incr; item = ll_get(conf_items, rv); } while (item->type == t_sep || (item->dep && !*item->dep)); return rv; } /* Perform selection, return offset value to ensure pad fits inside window */ static int m_pref(WINDOW *w_conf, int list_offset, int active_item, int num_items) { int active_line, i, j; werase(w_conf); for (active_line = i = j = 0; i < num_items; i++) { struct conf_item *item = ll_get(conf_items, i); if (!item->hidden && (!item->dep || *item->dep)) { if (i != active_item) waddstr_item(w_conf, j++, item, 0); else { waddstr_item(w_conf, j, item, 1); active_line = j++; } } } if (active_line - list_offset > MAX_NUM_CONF_ROWS) return active_line - MAX_NUM_CONF_ROWS; if (active_line < list_offset) return active_line; return list_offset; } void scr_conf_init(void) { struct conf_item *item; conf_get_interface_list(); /* may have changed in the meantime */ num_items = ll_size(conf_items); w_conf = newwin_title(0, WAV_HEIGHT, "Preferences", false); w_confpad = newpad(num_items + 1, CONF_SCREEN_WIDTH); if (first_item) /* already initialized */ return; while ((item = ll_get(conf_items, first_item)) && item->type == t_sep) first_item++; active_item = first_item; } int scr_conf_loop(WINDOW *w_menu) { struct conf_item *item; int key; list_offset = m_pref(w_confpad, list_offset, active_item, num_items); prefresh(w_confpad, list_offset, 0, 1, (WAV_WIDTH - CONF_SCREEN_WIDTH)/2, MAXYLEN, (WAV_WIDTH + CONF_SCREEN_WIDTH)/2); wrefresh(w_conf); key = wgetch(w_menu); switch (key) { case KEY_HOME: active_item = first_item; break; case KEY_END: active_item = num_items - 1; break; case KEY_DOWN: case KEY_NPAGE: active_item = select_item(active_item, 1); if (active_item >= num_items) { active_item = first_item; list_offset = 0; } break; case KEY_UP: case KEY_PPAGE: active_item = select_item(active_item, -1); if (active_item < first_item) active_item = num_items - 1; break; case KEY_LEFT: change_item(active_item, -1); break; case KEY_RIGHT: change_item(active_item, 1); break; case '\r': item = ll_get(conf_items, active_item); if (item->type == t_func) { flash(); (*item->v.fp)(); } } return key; } void scr_conf_fini(void) { delwin(w_conf); delwin(w_confpad); }