rockbox/apps/plugins/main_menu_config.c

247 lines
7.3 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 Jonathan Gordon
*
* 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.
*
****************************************************************************/
/* mandatory include for all plugins */
#include "plugin.h"
static struct menu_table *menu_table;
static int menu_item_count;
#define MAX_ITEM_NAME 64
#define MAX_ITEMS 16
struct items
{
unsigned char *name;
char string[MAX_ITEM_NAME];
bool enabled;
};
static struct items menu_items[MAX_ITEMS];
static const char * menu_get_name(int selected_item, void * data,
char * buffer, size_t buffer_len)
{
(void)data;
(void)buffer;
(void)buffer_len;
unsigned char *p = menu_items[selected_item].name;
int id = P2ID(p);
return (id != -1) ? rb->str(id) : p;
}
static enum themable_icons menu_get_icon(int selected_item, void * data)
{
(void)data;
return menu_items[selected_item].enabled ? Icon_Config : Icon_NOICON;
}
static unsigned char *item_name(int n)
{
const struct menu_item_ex *item = menu_table[n].item;
return (item->flags & MENU_HAS_DESC) ?
item->callback_and_desc->desc :
(rb->strcmp("wps", menu_table[n].string) ?
(unsigned char *)menu_table[n].string :
ID2P(LANG_RESUME_PLAYBACK));
}
void load_from_cfg(void)
{
char config_str[128];
char *token, *save;
int done = 0;
int i = 0;
bool found = false;
config_str[0] = '\0';
rb->root_menu_write_to_cfg(NULL, config_str, sizeof(config_str));
token = rb->strtok_r(config_str, ", ", &save);
while (token)
{
for (i = 0, found = false; i < menu_item_count; i++)
{
found = rb->strcmp(token, menu_table[i].string) == 0;
if (found) break;
}
if (found)
{
menu_items[done].name = item_name(i);
rb->strcpy(menu_items[done].string, token);
menu_items[done].enabled = true;
done++;
}
token = rb->strtok_r(NULL, ", ", &save);
}
if (done < menu_item_count)
{
for (i = 0; i < menu_item_count; i++)
{
found = false;
for (int j = 0; !found && j < done; j++)
{
found = rb->strcmp(menu_table[i].string, menu_items[j].string) == 0;
}
if (!found)
{
menu_items[done].name = item_name(i);
rb->strcpy(menu_items[done].string, menu_table[i].string);
menu_items[done].enabled = false;
done++;
}
}
}
}
static void save_to_cfg(void)
{
char out[128];
int i, j = 0;
out[0] = '\0';
for (i = 0; i < menu_item_count; i++)
{
if (menu_items[i].enabled)
{
j += rb->snprintf(&out[j],sizeof(out) - j, "%s, ", menu_items[i].string);
}
}
rb->root_menu_load_from_cfg(&rb->global_settings->root_menu_customized, out);
}
static void swap_items(int a, int b)
{
unsigned char *name;
char temp[MAX_ITEM_NAME];
bool enabled;
name = menu_items[a].name;
rb->strcpy(temp, menu_items[a].string);
enabled = menu_items[a].enabled;
menu_items[a].name = menu_items[b].name;
rb->strcpy(menu_items[a].string,
menu_items[b].string);
menu_items[a].enabled = menu_items[b].enabled;
menu_items[b].name = name;
rb->strcpy(menu_items[b].string, temp);
menu_items[b].enabled = enabled;
}
static int menu_speak_item(int selected_item, void *data)
{
(void) data;
int id = P2ID(menu_items[selected_item].name);
if (id != -1)
{
rb->talk_id(id, false);
rb->talk_id(menu_items[selected_item].enabled ? LANG_ON : LANG_OFF, true);
}
return 0;
}
/* this is the plugin entry point */
enum plugin_status plugin_start(const void* parameter)
{
(void)parameter;
struct gui_synclist list;
bool done = false;
int action, cur_sel;
menu_table = rb->root_menu_get_options(&menu_item_count);
load_from_cfg();
rb->gui_synclist_init(&list, menu_get_name, NULL, false, 1, NULL);
if (rb->global_settings->talk_menu)
rb->gui_synclist_set_voice_callback(&list, menu_speak_item);
rb->gui_synclist_set_icon_callback(&list, menu_get_icon);
rb->gui_synclist_set_nb_items(&list, menu_item_count);
rb->gui_synclist_set_title(&list, rb->str(LANG_MAIN_MENU_ORDER), Icon_Rockbox);
rb->gui_synclist_draw(&list);
rb->gui_synclist_speak_item(&list);
while (!done)
{
cur_sel = rb->gui_synclist_get_sel_pos(&list);
action = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK);
if (rb->gui_synclist_do_button(&list,&action,LIST_WRAP_UNLESS_HELD))
continue;
switch (action)
{
case ACTION_STD_OK:
{
MENUITEM_STRINGLIST(menu, "Main Menu Editor", NULL,
ID2P(LANG_TOGGLE_ITEM),
ID2P(LANG_MOVE_ITEM_UP),
ID2P(LANG_MOVE_ITEM_DOWN),
"----------",
ID2P(LANG_LOAD_DEFAULT_CONFIGURATION),
ID2P(LANG_SAVE_EXIT));
switch (rb->do_menu(&menu, NULL, NULL, false))
{
case 0:
menu_items[cur_sel].enabled = !menu_items[cur_sel].enabled;
break;
case 1:
if (cur_sel == 0)
break;
swap_items(cur_sel, cur_sel - 1);
break;
case 2:
if (cur_sel + 1 == menu_item_count)
break;
swap_items(cur_sel, cur_sel + 1);
break;
case 4:
rb->root_menu_set_default(&rb->global_settings->root_menu_customized, NULL);
load_from_cfg();
break;
case 5:
done = true;
save_to_cfg();
rb->global_settings->root_menu_customized = true;
rb->settings_save();
break;
}
if (!done)
{
rb->gui_synclist_draw(&list);
rb->gui_synclist_speak_item(&list);
}
break;
}
case ACTION_STD_CANCEL:
done = true;
break;
}
}
return PLUGIN_OK;
}