rockbox/apps/plugins/lib/oldmenuapi.c
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
later. We still need to hunt down snippets used that are not. 1324 modified
files...
http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
2008-06-28 18:10:04 +00:00

241 lines
6.6 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 Robert E. Hak
*
* This program 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
* of the License, or (at your option) any later version.
*
* 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 <stdbool.h>
#include <stdlib.h>
#include "plugin.h"
#include "oldmenuapi.h"
const struct plugin_api *rb = NULL;
struct menu {
struct menu_item* items;
int (*callback)(int, int);
struct gui_synclist synclist;
};
#define MAX_MENUS 6
static struct menu menus[MAX_MENUS];
static bool inuse[MAX_MENUS] = { false };
static char * menu_get_itemname(int selected_item, void * data,
char *buffer, size_t buffer_len)
{
(void)buffer; (void)buffer_len;
struct menu *local_menus=(struct menu *)data;
return(local_menus->items[selected_item].desc);
}
static int menu_find_free(void)
{
int i;
/* Tries to find an unused slot to put the new menu */
for ( i=0; i<MAX_MENUS; i++ ) {
if ( !inuse[i] ) {
inuse[i] = true;
break;
}
}
if ( i == MAX_MENUS ) {
DEBUGF("Out of menus!\n");
return -1;
}
return(i);
}
int menu_init(const struct plugin_api *api, const struct menu_item* mitems,
int count, int (*callback)(int, int),
const char *button1, const char *button2, const char *button3)
{
int menu=menu_find_free();
rb = api;
if(menu==-1)/* Out of menus */
return -1;
menus[menu].items = (struct menu_item*)mitems; /* de-const */
rb->gui_synclist_init(&(menus[menu].synclist),
&menu_get_itemname, &menus[menu], false, 1, NULL);
rb->gui_synclist_set_icon_callback(&(menus[menu].synclist), NULL);
rb->gui_synclist_set_nb_items(&(menus[menu].synclist), count);
menus[menu].callback = callback;
(void)button1;
(void)button2;
(void)button3;
return menu;
}
void menu_exit(int m)
{
inuse[m] = false;
}
int menu_show(int m)
{
bool exit = false;
int key;
rb->gui_synclist_draw(&(menus[m].synclist));
rb->gui_syncstatusbar_draw(rb->statusbars, true);
while (!exit) {
key = rb->get_action(CONTEXT_MAINMENU,HZ/2);
/*
* "short-circuit" the default keypresses by running the
* callback function
* The callback may return a new key value, often this will be
* BUTTON_NONE or the same key value, but it's perfectly legal
* to "simulate" key presses by returning another value.
*/
if( menus[m].callback != NULL )
key = menus[m].callback(key, m);
rb->gui_synclist_do_button(&(menus[m].synclist), &key,LIST_WRAP_UNLESS_HELD);
switch( key ) {
case ACTION_STD_OK:
return rb->gui_synclist_get_sel_pos(&(menus[m].synclist));
case ACTION_STD_CANCEL:
case ACTION_STD_MENU:
case SYS_POWEROFF:
exit = true;
break;
default:
if(rb->default_event_handler(key) == SYS_USB_CONNECTED)
return MENU_ATTACHED_USB;
break;
}
rb->gui_syncstatusbar_draw(rb->statusbars, false);
}
return MENU_SELECTED_EXIT;
}
bool menu_run(int m)
{
int selected;
while (1) {
switch (selected=menu_show(m))
{
case MENU_SELECTED_EXIT:
return false;
case MENU_ATTACHED_USB:
return true;
default:
{
if (menus[m].items[selected].function &&
menus[m].items[selected].function())
return true;
rb->gui_syncstatusbar_draw(rb->statusbars, true);
}
}
}
return false;
}
/*
* Property function - return the current cursor for "menu"
*/
int menu_cursor(int menu)
{
return rb->gui_synclist_get_sel_pos(&(menus[menu].synclist));
}
/*
* Property function - return the "menu" description at "position"
*/
char* menu_description(int menu, int position)
{
return menus[menu].items[position].desc;
}
/*
* Delete the element "position" from the menu items in "menu"
*/
void menu_delete(int menu, int position)
{
int i;
int nb_items=rb->gui_synclist_get_nb_items(&(menus[menu].synclist));
/* copy the menu item from the one below */
for( i = position; i < nb_items - 1; i++)
menus[menu].items[i] = menus[menu].items[i + 1];
rb->gui_synclist_del_item(&(menus[menu].synclist));
}
void menu_insert(int menu, int position, char *desc, bool (*function) (void))
{
int i;
int nb_items=rb->gui_synclist_get_nb_items(&(menus[menu].synclist));
if(position < 0)
position = nb_items;
/* Move the items below one position forward */
for( i = nb_items; 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;
rb->gui_synclist_add_item(&(menus[menu].synclist));
}
/*
* Property function - return the "count" of menu items in "menu"
*/
int menu_count(int menu)
{
return rb->gui_synclist_get_nb_items(&(menus[menu].synclist));
}
/*
* Allows to set the cursor position. Doesn't redraw by itself.
*/
void menu_set_cursor(int menu, int position)
{
rb->gui_synclist_select_item(&(menus[menu].synclist), position);
}
#if 0
void menu_talk_selected(int m)
{
if(rb->global_settings->talk_menu)
{
int selected=rb->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 */
}
}
#endif
void menu_draw(int m)
{
rb->gui_synclist_draw(&(menus[m].synclist));
}