/* Terminality - a portable terminal handling library * Copyright (C) 1998-2002, Emil Mikulic. * This is LGPL - look at COPYING.LIB */ /* Project: Terminality/GUI * File: menu.cpp * Author: Emil Mikulic, Michal Safranek * Description: Implement the menuitem and menu classes */ /* Define if you want infinite menu loop (last->first && last<-first) */ #define INFINITE_LOOP #include const char menu_rcsid[] = "$Id: menu.cpp,v 1.14 2002/07/26 01:39:40 darkmoon Exp $"; // Initialise menuItem menuItem::menuItem() { name = NULL; id = -1; }; // Initialise menuItem menuItem::menuItem(char *n, int i) { name = (char *)xmalloc(strlen(n)+1); strcpy(name, n); id = i; }; // Destroy menuItem menuItem::~menuItem() { xfree(name); }; // Initialise menu list menu::menu(menuItem *i, ...) { va_list va; menuItem *curr; visible = fixed_colors = false; width = height = 0; current = 0; item = NULL; // colors SCROLL = COLOR_MENU_SCROLL; FRAME = COLOR_MENU_FRAME; CORNER = COLOR_MENU_CORNER; ITEM = COLOR_MENU_ITEM; FRAME_BG = COLOR_MENU_FRAMEBG; ITEM_BG = COLOR_MENU_ITEMBG; SELECTED_ITEM = COLOR_MENU_SITEM; SELECTED_ITEM_BG = COLOR_MENU_SITEMBG; // start the va_list va_start(va, i); curr = i; // as long as the item isn't a NULL while (curr) { // add to queue if (!item) item = tn_list_new((void*)curr); else tn_list_add(item, (void*)curr); // check against width if (strlen(curr->name) > (unsigned) width) width = strlen(curr->name); // get next item curr = va_arg(va, menuItem*); } va_end(va); // get list size count = tn_list_size(item); // fix menu height height = count; if (height > CON_ROWS-2) height = CON_ROWS-2; scroll = 0; // make up x/y coords x = (CON_COLS-width-2) / 2; y = (CON_ROWS-height-2) / 2; if (!y) y=1; reg_id = register_add(Menu, this); } // destroy menu list menu::~menu() { // first kill all menuItems menuItem *tmp; for (int i=0; iid == -1) { // safe enough for (int j=0; jname); // Finish padding line with highlight bar for (int pad=strlen(tmp->name); padscroll+height-1) scroll++; } else { current = 0; scroll = 0; } #else if (currentscroll+height-1) scroll++; #endif break; case KEY_HOME: scroll = 0; current = 0; break; case KEY_END: scroll = count - height; current = count - 1; break; case KEY_PGUP: current -= height-1; if (current<0) current = 0; if (scroll>current) scroll = current; break; case KEY_PGDOWN: current += height-1; if (current >= count) current = count-1; if (current >= scroll+height) scroll += height; if (scroll+height > count) scroll = count-height; break; case KEY_ENTER: // can't accept an item with id -1 temp = (menuItem*)tn_list_getdata(item, current); if (temp->id != -1){ set_cursor(cs); visible = old_vis; return temp->id; } break; case KEY_ESC: set_cursor(cs); visible = old_vis; return -1; default: beep(); } } } // set height int menu::setheight(int h) { if (h && h <= tn_list_size(item)) { height = h; } return height; } // Change scheme void menu::change_scheme(void) { if (fixed_colors) return; SCROLL = COLOR_MENU_SCROLL; FRAME = COLOR_MENU_FRAME; CORNER = COLOR_MENU_CORNER; ITEM = COLOR_MENU_ITEM; FRAME_BG = COLOR_MENU_FRAMEBG; ITEM_BG = COLOR_MENU_ITEMBG; SELECTED_ITEM = COLOR_MENU_SITEM; SELECTED_ITEM_BG = COLOR_MENU_SITEMBG; }