/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2002 Robert E. Hak * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ /* 2005 Kevin Ferrare : - Multi screen support - Rewrote/removed a lot of code now useless with the new gui API */ #include #include #include "hwcompat.h" #include "lcd.h" #include "font.h" #include "backlight.h" #include "menu.h" #include "button.h" #include "kernel.h" #include "debug.h" #include "usb.h" #include "panic.h" #include "settings.h" #include "status.h" #include "screens.h" #include "talk.h" #include "lang.h" #include "misc.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" #endif /* gui api */ #include "list.h" #include "statusbar.h" #include "buttonbar.h" struct menu { struct menu_item* items; int (*callback)(int, int); #ifdef HAS_BUTTONBAR struct gui_buttonbar buttonbar; #endif struct gui_synclist synclist; }; #define MAX_MENUS 5 static struct menu menus[MAX_MENUS]; static bool inuse[MAX_MENUS] = { false }; char * menu_get_itemname(int selected_item, void * data, char *buffer) { struct menu *local_menus=(struct menu *)data; (void)buffer; return(P2STR(local_menus->items[selected_item].desc)); } int menu_find_free(void) { int i; /* Tries to find an unused slot to put the new menu */ for ( i=0; i position; i--) menus[menu].items[i] = menus[menu].items[i - 1]; /* Update the current item */ menus[menu].items[position].desc = (unsigned char *)desc; menus[menu].items[position].function = function; gui_synclist_add_item(&(menus[menu].synclist)); } /* * Property function - return the "count" of menu items in "menu" */ int menu_count(int menu) { return gui_synclist_get_nb_items(&(menus[menu].synclist)); } /* * Allows a menu item at the current cursor position in "menu" * to be moved up the list */ bool menu_moveup(int menu) { struct menu_item swap; int selected=menu_cursor(menu); /* can't be the first item ! */ if( selected == 0) return false; /* use a temporary variable to do the swap */ swap = menus[menu].items[selected - 1]; menus[menu].items[selected - 1] = menus[menu].items[selected]; menus[menu].items[selected] = swap; gui_synclist_select_previous(&(menus[menu].synclist)); return true; } /* * Allows a menu item at the current cursor position in "menu" to be moved down the list */ bool menu_movedown(int menu) { struct menu_item swap; int selected=menu_cursor(menu); int nb_items=gui_synclist_get_nb_items(&(menus[menu].synclist)); /* can't be the last item ! */ if( selected == nb_items - 1) return false; /* use a temporary variable to do the swap */ swap = menus[menu].items[selected + 1]; menus[menu].items[selected + 1] = menus[menu].items[selected]; menus[menu].items[selected] = swap; gui_synclist_select_next(&(menus[menu].synclist)); return true; } /* * Allows to set the cursor position. Doesn't redraw by itself. */ void menu_set_cursor(int menu, int position) { gui_synclist_select_item(&(menus[menu].synclist), position); } void menu_talk_selected(int m) { if(global_settings.talk_menu) { int selected=gui_synclist_get_sel_pos(&(menus[m].synclist)); int voice_id = P2ID(menus[m].items[selected].desc); if (voice_id >= 0) /* valid ID given? */ talk_id(voice_id, false); /* say it */ } } void menu_draw(int m) { gui_synclist_draw(&(menus[m].synclist)); } /* count in letter positions, NOT pixels */ void put_cursorxy(int x, int y, bool on) { #ifdef HAVE_LCD_BITMAP int fh, fw; int xpos, ypos; /* check here instead of at every call (ugly, but cheap) */ if (global_settings.invert_cursor) return; lcd_getstringsize((unsigned char *)"A", &fw, &fh); xpos = x*6; ypos = y*fh + lcd_getymargin(); if ( fh > 8 ) ypos += (fh - 8) / 2; #endif /* place the cursor */ if(on) { #ifdef HAVE_LCD_BITMAP lcd_mono_bitmap(bitmap_icons_6x8[Icon_Cursor], xpos, ypos, 4, 8); #else lcd_putc(x, y, CURSOR_CHAR); #endif } else { #if defined(HAVE_LCD_BITMAP) /* I use xy here since it needs to disregard the margins */ lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); lcd_fillrect (xpos, ypos, 4, 8); lcd_set_drawmode(DRMODE_SOLID); #else lcd_putc(x, y, ' '); #endif } }