Introducing the root menu!

Blind users: get a new voice file as there are lots of lang changes and new strings.
FS#6630 or RootMenu on the wiki for more info. complaints to /dev/null :)



git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12528 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2007-03-01 11:14:46 +00:00
parent d94c7d3f76
commit 91cb68a1fb
41 changed files with 852 additions and 363 deletions

View file

@ -29,6 +29,7 @@ playlist.c
playlist_catalog.c
playlist_viewer.c
plugin.c
root_menu.c
screens.c
settings.c
settings_list.c

View file

@ -160,6 +160,7 @@ enum {
once the subitem returns */
ACTION_ENTER_MENUITEM,
ACTION_MENU_WPS,
ACTION_MENU_STOP,
/* id3db */

View file

@ -59,6 +59,7 @@
#include "backdrop.h"
#endif
#include "ata_idle_notify.h"
#include "root_menu.h"
#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
@ -238,7 +239,9 @@ long gui_wps_show(void)
show_main_backdrop();
#endif
action_signalscreenchange();
onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS);
if (onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS)
== ONPLAY_MAINMENU)
return GO_TO_ROOT;
#if LCD_DEPTH > 1
show_wps_backdrop();
#endif
@ -258,13 +261,8 @@ long gui_wps_show(void)
#endif
FOR_NB_SCREENS(i)
gui_wps[i].display->stop_scroll();
/* set dir browser to current playing song */
if (global_settings.browse_current &&
wps_state.current_track_path[0] != '\0')
set_current_file(wps_state.current_track_path);
action_signalscreenchange();
return 0;
return GO_TO_PREVIOUS_BROWSER;
break;
/* play/pause */
@ -497,23 +495,7 @@ long gui_wps_show(void)
case ACTION_WPS_MENU:
FOR_NB_SCREENS(i)
gui_wps[i].display->stop_scroll();
#if LCD_DEPTH > 1
show_main_backdrop();
#endif
action_signalscreenchange();
if (main_menu())
return true;
#if LCD_DEPTH > 1
show_wps_backdrop();
#endif
#ifdef HAVE_LCD_BITMAP
FOR_NB_SCREENS(i)
{
gui_wps_set_margin(&gui_wps[i]);
}
#endif
restore = true;
return GO_TO_ROOT;
break;
@ -639,12 +621,7 @@ long gui_wps_show(void)
}
if (update_failed)
{
/* set dir browser to current playing song */
if (global_settings.browse_current &&
wps_state.current_track_path[0] != '\0')
set_current_file(wps_state.current_track_path);
return 0;
return GO_TO_ROOT;
}
update_track = false;
}
@ -666,12 +643,7 @@ long gui_wps_show(void)
ab_reset_markers();
#endif
/* set dir browser to current playing song */
if (global_settings.browse_current &&
wps_state.current_track_path[0] != '\0')
set_current_file(wps_state.current_track_path);
return 0;
return GO_TO_PREVIOUS;
}
if ( button )
@ -685,12 +657,7 @@ long gui_wps_show(void)
restoretimer = 0;
if (gui_wps_display())
{
/* set dir browser to current playing song */
if (global_settings.browse_current &&
wps_state.current_track_path[0] != '\0')
set_current_file(wps_state.current_track_path);
return 0;
return GO_TO_ROOT;
}
if (wps_state.id3){
@ -699,7 +666,7 @@ long gui_wps_show(void)
}
}
}
return 0; /* unreachable - just to reduce compiler warnings */
return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
}
/* needs checking if needed end*/

View file

@ -48,6 +48,12 @@ static const struct button_mapping button_context_standard[] = {
LAST_ITEM_IN_LIST
}; /* button_context_standard */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_UP, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_UP|BUTTON_REL, BUTTON_UP },
{ ACTION_WPS_STOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP },
@ -228,8 +234,9 @@ const struct button_mapping* get_context_mapping(int context)
switch (context)
{
case CONTEXT_STD:
case CONTEXT_MAINMENU:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_WPS:
return button_context_wps;

View file

@ -116,6 +116,15 @@ static const struct button_mapping button_context_tree[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_tree */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_MENU_STOP, BUTTON_A, BUTTON_NONE },
{ ACTION_MENU_STOP, BUTTON_A|BUTTON_REL, BUTTON_A },
{ ACTION_MENU_STOP, BUTTON_A|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_tree */
static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
{ ACTION_NONE, BUTTON_POWER, BUTTON_NONE },
{ ACTION_TREE_PGLEFT, BUTTON_POWER|BUTTON_LEFT, BUTTON_POWER },
@ -259,8 +268,9 @@ const struct button_mapping* get_context_mapping(int context)
switch (context)
{
case CONTEXT_STD:
case CONTEXT_MAINMENU:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_WPS:
return button_context_wps;

View file

@ -62,6 +62,12 @@ static const struct button_mapping remote_button_context_standard[] = {
LAST_ITEM_IN_LIST
}; /* remote_button_context_standard */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT,BUTTON_PLAY },
@ -351,8 +357,9 @@ const struct button_mapping* get_context_mapping(int context)
switch (context)
{
case CONTEXT_STD:
case CONTEXT_MAINMENU:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_WPS:
return button_context_wps;

View file

@ -65,6 +65,12 @@ static const struct button_mapping button_context_standard[] = {
LAST_ITEM_IN_LIST
}; /* button_context_standard */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_ON, BUTTON_NONE },
{ ACTION_MENU_STOP, BUTTON_OFF, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_ON|BUTTON_REL, BUTTON_ON },
@ -715,10 +721,18 @@ static const struct button_mapping button_context_radio_h300lcdremote[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
};
static const struct button_mapping button_context_menu_remote[] = {
{ ACTION_MENU_STOP, BUTTON_RC_STOP, BUTTON_NONE },
{ ACTION_MENU_WPS, BUTTON_RC_ON, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
};
/* the actual used tables */
static const struct button_mapping
*remote_btn_ctxt_std = 0,
*remote_btn_ctxt_wps = 0,
*remote_btn_ctxt_menu = button_context_menu_remote,
*remote_btn_ctxt_list = 0,
*remote_btn_ctxt_tree = 0,
*remote_btn_ctxt_listtree_scroll_w_cmb = 0,
@ -866,8 +880,9 @@ static const struct button_mapping* get_context_mapping_remote(int context)
switch (context)
{
case CONTEXT_STD:
case CONTEXT_MAINMENU:
return remote_btn_ctxt_std;
case CONTEXT_MAINMENU:
return remote_btn_ctxt_menu;
case CONTEXT_WPS: /* common for all remotes */
return button_context_wps_remotescommon;
@ -914,8 +929,9 @@ const struct button_mapping* get_context_mapping(int context)
switch (context)
{
case CONTEXT_STD:
case CONTEXT_MAINMENU:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_WPS:
return button_context_wps;

View file

@ -60,6 +60,12 @@ static const struct button_mapping button_context_tree[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_tree */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_MENU_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_tree_scroll_lr[] = {
{ ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
@ -191,8 +197,9 @@ const struct button_mapping* get_context_mapping(int context)
return button_context_tree;
case CONTEXT_LIST:
case CONTEXT_MAINMENU:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_SETTINGS_EQ:
case CONTEXT_SETTINGS_COLOURCHOOSER:

View file

@ -83,10 +83,17 @@ static const struct button_mapping button_context_settings[] = {
static const struct button_mapping button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
{ ACTION_TREE_STOP, BUTTON_OFF, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_listtree */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_tree_scroll_lr[] = {
{ ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
@ -211,8 +218,9 @@ const struct button_mapping* get_context_mapping( int context )
case CONTEXT_FM:
return button_context_radio;
#endif
case CONTEXT_LIST:
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_LIST:
default:
return button_context_standard;
}

View file

@ -78,6 +78,12 @@ static const struct button_mapping button_context_tree[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_listtree */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_ON, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_menu */
static const struct button_mapping button_context_yesno[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
@ -153,9 +159,10 @@ const struct button_mapping* get_context_mapping( int context )
return button_context_tree;
case CONTEXT_BOOKMARKSCREEN:
return button_context_bmark;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_STD:
case CONTEXT_LIST:
case CONTEXT_MAINMENU:
default:
return button_context_standard;
}

View file

@ -112,6 +112,13 @@ static const struct button_mapping button_context_tree[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_listtree */
static const struct button_mapping button_context_menu[] = {
{ ACTION_MENU_WPS, BUTTON_ON|BUTTON_REL, BUTTON_ON },
{ ACTION_MENU_STOP, BUTTON_OFF, BUTTON_NONE },
{ ACTION_NONE, BUTTON_ON, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_listtree */
static const struct button_mapping button_context_tree_scroll_lr[] = {
{ ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
@ -299,9 +306,10 @@ const struct button_mapping* get_context_mapping( int context )
case CONTEXT_FM:
return button_context_radio;
case CONTEXT_MAINMENU:
return button_context_menu;
case CONTEXT_STD:
case CONTEXT_LIST:
case CONTEXT_MAINMENU:
default:
return button_context_standard;
}

View file

@ -117,7 +117,7 @@ static const struct button_mapping button_context_keyboard[] = {
/* Main Menu Context Menu **/
static const struct button_mapping button_context_mainmenu[] = {
{ ACTION_NONE, BUTTON_POWER, BUTTON_NONE },
{ ACTION_MENU_WPS, BUTTON_PLAY, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_mainmenu */

View file

@ -314,13 +314,13 @@
desc: in the main menu
user:
<source>
*: "Playlist Options"
*: "Playlist"
</source>
<dest>
*: "Playlist Options"
*: "Playlist"
</dest>
<voice>
*: "Playlist Options"
*: "Playlist"
</voice>
</phrase>
<phrase>
@ -328,13 +328,13 @@
desc: in the main menu
user:
<source>
*: "Browse Plugins"
*: "Plugins"
</source>
<dest>
*: "Browse Plugins"
*: "Plugins"
</dest>
<voice>
*: "Browse Plugins"
*: "Plugins"
</voice>
</phrase>
<phrase>
@ -342,13 +342,13 @@
desc: in the main menu
user:
<source>
*: "Info"
*: "System"
</source>
<dest>
*: "Info"
*: "System"
</dest>
<voice>
*: "Info"
*: "System"
</voice>
</phrase>
<phrase>
@ -1008,13 +1008,13 @@
desc: in the recording sub menu
user:
<source>
*: "Recording Screen"
*: "Recording"
</source>
<dest>
*: "Recording Screen"
*: "Recording"
</dest>
<voice>
*: "Recording Screen"
*: "Recording"
</voice>
</phrase>
<phrase>
@ -10563,3 +10563,115 @@
*: "FM Radio Menu"
</voice>
</phrase>
<phrase>
id: LANG_DIR_BROWSER
desc: in root menu
user:
<source>
*: "Files"
</source>
<dest>
*: "Files"
</dest>
<voice>
*: "Files"
</voice>
</phrase>
<phrase>
id: LANG_SETTINGS_MENU
desc: in root menu
user:
<source>
*: "Settings"
</source>
<dest>
*: "Settings"
</dest>
<voice>
*: "Settings"
</voice>
</phrase>
<phrase>
id: LANG_NOW_PLAYING
desc: in root menu
user:
<source>
*: "Now Playing"
</source>
<dest>
*: "Now Playing"
</dest>
<voice>
*: "Now Playing"
</voice>
</phrase>
<phrase>
id: LANG_RESUME_PLAYBACK
desc: in root menu
user:
<source>
*: "Resume Playback"
</source>
<dest>
*: "Resume Playback"
</dest>
<voice>
*: "Resume Playback"
</voice>
</phrase>
<phrase>
id: LANG_START_SCREEN
desc: in root menu setting
user:
<source>
*: "Start Screen"
</source>
<dest>
*: "Start Screen"
</dest>
<voice>
*: "Start Screen"
</voice>
</phrase>
<phrase>
id: LANG_ROCKBOX_TITLE
desc: in root menu
user:
<source>
*: "Rockbox"
</source>
<dest>
*: "Rockbox"
</dest>
<voice>
*: "Rockbox"
</voice>
</phrase>
<phrase>
id: LANG_MAIN_MENU
desc: in root menu setting
user:
<source>
*: "Main Menu"
</source>
<dest>
*: "Main Menu"
</dest>
<voice>
*: "Main Menu"
</voice>
</phrase>
<phrase>
id: LANG_PREVIOUS_SCREEN
desc: in root menu setting
user:
<source>
*: "Previous Screen"
</source>
<dest>
*: "Previous Screen"
</dest>
<voice>
*: "Previous Screen"
</voice>
</phrase>

View file

@ -128,9 +128,6 @@ bool main_menu(void)
if(inside_menu) return false;
inside_menu = true;
items[i].desc = ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS);
items[i++].function = bookmark_mrb_load;
items[i].desc = ID2P(LANG_SOUND_SETTINGS);
items[i++].function = sound_menu;

View file

@ -21,7 +21,7 @@
#include "menu.h"
extern bool main_menu(void);
extern int main_menu(void);
extern bool rec_menu(void);
#endif

View file

@ -23,6 +23,7 @@
*/
#include <stdbool.h>
#include <stdlib.h>
#include "config.h"
#include "hwcompat.h"
#include "lcd.h"
@ -44,6 +45,10 @@
#include "action.h"
#include "menus/exported_menus.h"
#include "string.h"
#include "root_menu.h"
#include "bookmark.h"
#include "gwps-common.h" /* for fade() */
#include "audio.h"
#ifdef HAVE_LCD_BITMAP
#include "icons.h"
@ -303,7 +308,14 @@ static int get_menu_selection(int selected_item, const struct menu_item_ex *menu
return current_subitems[selected_item];
return selected_item;
}
static int find_menu_selection(int selected)
{
int i;
for (i=0; i< current_subitems_count; i++)
if (current_subitems[i] == selected)
return i;
return 0;
}
static char * get_menu_item_name(int selected_item,void * data, char *buffer)
{
const struct menu_item_ex *menu = (const struct menu_item_ex *)data;
@ -363,6 +375,7 @@ static void menu_get_icon(int selected_item, void * data, ICON * icon)
break;
case MT_FUNCTION_CALL:
case MT_FUNCTION_WITH_PARAM:
case MT_RETURN_VALUE:
if (menu_icon == NOICON)
*icon = bitmap_icons_6x8[Icon_Menu_functioncall];
else
@ -418,7 +431,7 @@ static void init_menu_lists(const struct menu_item_ex *menu,
gui_synclist_set_icon_callback(lists, NULL);
gui_synclist_set_nb_items(lists,current_subitems_count);
gui_synclist_limit_scroll(lists,true);
gui_synclist_select_item(lists, selected);
gui_synclist_select_item(lists, find_menu_selection(selected));
get_menu_callback(menu,&menu_callback);
if (callback && menu_callback)
@ -434,14 +447,14 @@ static void talk_menu_item(const struct menu_item_ex *menu,
int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
{
if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
talk_setting(menu->submenus[sel]->variable);
else
{
id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
if (id != -1)
if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
talk_setting(menu->submenus[sel]->variable);
else
{
id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
if (id != -1)
talk_id(id,false);
}
}
}
}
}
@ -564,10 +577,10 @@ bool do_setting_from_menu(const struct menu_item_ex *temp)
return ret_val;
}
int do_menu(const struct menu_item_ex *start_menu)
int do_menu(const struct menu_item_ex *start_menu, int *start_selected)
{
int selected = start_selected? *start_selected : 0;
int action;
int selected = 0;
struct gui_synclist lists;
const struct menu_item_ex *temp, *menu;
int ret = 0;
@ -630,10 +643,24 @@ int do_menu(const struct menu_item_ex *start_menu)
}
else if (action == ACTION_MENU_WPS)
{
ret = MENU_RETURN_TO_WPS;
ret = GO_TO_PREVIOUS_MUSIC;
}
else if ((action == ACTION_STD_CANCEL) ||
(action == ACTION_STD_MENU))
else if (action == ACTION_MENU_STOP)
{
if (audio_status() && !global_settings.party_mode)
{
if (global_settings.fade_on_stop)
fade(0);
bookmark_autobookmark();
audio_stop();
}
}
else if (action == ACTION_STD_MENU)
{
if (menu != &root_menu_)
ret = GO_TO_ROOT;
}
else if (action == ACTION_STD_CANCEL)
{
in_stringlist = false;
if (menu_callback)
@ -649,8 +676,11 @@ int do_menu(const struct menu_item_ex *start_menu)
/* new menu, so reload the callback */
get_menu_callback(menu, &menu_callback);
}
else
else if (menu != &root_menu_)
{
ret = GO_TO_PREVIOUS;
break;
}
}
else if (action == ACTION_STD_OK)
{
@ -678,8 +708,7 @@ int do_menu(const struct menu_item_ex *start_menu)
if (stack_top < MAX_MENUS)
{
menu_stack[stack_top] = menu;
menu_stack_selected_item[stack_top]
= gui_synclist_get_sel_pos(&lists);
menu_stack_selected_item[stack_top] = selected;
stack_top++;
init_menu_lists(temp, &lists, 0, true);
menu = temp;
@ -717,6 +746,10 @@ int do_menu(const struct menu_item_ex *start_menu)
in_stringlist = true;
}
break;
case MT_RETURN_VALUE:
if (start_selected)
*start_selected = selected;
return temp->value;
}
if (type != MT_MENU && menu_callback)
menu_callback(ACTION_EXIT_MENUITEM,temp);
@ -733,10 +766,12 @@ int do_menu(const struct menu_item_ex *start_menu)
gui_synclist_draw(&lists);
}
action_signalscreenchange();
if (start_selected)
*start_selected = selected;
return ret;
}
int main_menu(void)
{
return do_menu(NULL);
return do_menu(NULL, 0);
}

View file

@ -63,6 +63,7 @@ enum menu_item_type {
MT_FUNCTION_CALL, /* used when the standard code wont work */
MT_FUNCTION_WITH_PARAM,
MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
MT_RETURN_VALUE, /* returns a value associated with an item */
};
typedef int (*menu_function)(void);
@ -89,6 +90,7 @@ struct menu_item_ex {
const struct menu_func_with_param
*func_with_param; /* MT_FUNCTION_WITH_PARAM */
const char **strings; /* used with MT_RETURN_ID */
int value; /* MT_RETURN_VALUE */
};
union {
/* For settings */
@ -117,7 +119,7 @@ struct menu_item_ex {
typedef int (*menu_callback_type)(int action,
const struct menu_item_ex *this_item);
int do_menu(const struct menu_item_ex *menu);
int do_menu(const struct menu_item_ex *menu, int *start_selected);
bool do_setting_from_menu(const struct menu_item_ex *temp);
#define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT)
@ -149,22 +151,37 @@ bool do_setting_from_menu(const struct menu_item_ex *temp);
#ifdef HAVE_LCD_BITMAP /* Kill the player port already.... PLEASE!! */
/* This one should be static'ed also,
but cannot be done untill settings menu is done */
/* returns a value associated with the item */
#define MENUITEM_RETURNVALUE(name, str, val, cb, icon) \
static const struct menu_callback_with_desc name##_ = {cb,str,icon}; \
static const struct menu_item_ex name = \
{ MT_RETURN_VALUE|MENU_HAS_DESC, { .value = val}, \
{.callback_and_desc = & name##_}};
/* same as above, except the item name is dynamic */
#define MENUITEM_RETURNVALUE_DYNTEXT(name, val, cb, text_callback, text_cb_data, icon) \
static const struct menu_get_name_and_icon name##_ \
= {cb,text_callback,text_cb_data,icon}; \
static const struct menu_item_ex name = \
{ MT_RETURN_VALUE|MENU_DYNAMIC_DESC, { .value = val}, \
{.menu_get_name_and_icon = & name##_}};
/* Use this to put a function call into the menu.
When the user selects this item the function will be run,
when it exits the user will be back in the menu. return value is ignored */
#define MENUITEM_FUNCTION(name, str, func, callback, icon) \
static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \
const struct menu_item_ex name = \
static const struct menu_item_ex name = \
{ MT_FUNCTION_CALL|MENU_HAS_DESC, { .function = func}, \
{.callback_and_desc = & name##_}};
/* This one should be static'ed also,
but cannot be done untill recording menu is done */
/* Same as above, except the function will be called with a (void*)param. */
#define MENUITEM_FUNCTION_WPARAM(name, str, func, param, callback, icon) \
static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \
static const struct menu_func_with_param name##__ = {func, param}; \
static const struct menu_item_ex name = \
const struct menu_item_ex name = \
{ MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC, \
{ .func_with_param = &name##__}, \
{.callback_and_desc = & name##_}};
@ -189,8 +206,20 @@ bool do_setting_from_menu(const struct menu_item_ex *temp);
{MT_MENU|MENU_HAS_DESC| \
MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \
{ (void*)name##_},{.callback_and_desc = & name##__}};
#else /* HAVE_LCD_BITMAP */
#define MENUITEM_RETURNVALUE(name, str, val, cb, icon) \
static const struct menu_callback_with_desc name##_ = {cb,str}; \
static const struct menu_item_ex name = \
{ MT_RETURN_VALUE|MENU_HAS_DESC, { .value = val}, \
{.callback_and_desc = & name##_}};
#define MENUITEM_RETURNVALUE_DYNTEXT(name, val, cb, text_callback, text_cb_data, icon) \
static const struct menu_get_name_and_icon name##_ \
= {cb,text_callback,text_cb_data}; \
static const struct menu_item_ex name = \
{ MT_RETURN_VALUE|MENU_DYNAMIC_DESC, { .value = val}, \
{.menu_get_name_and_icon = & name##_}};
#define MENUITEM_FUNCTION(name, str, func, callback, icon) \
static const struct menu_callback_with_desc name##_ = {callback,str}; \
const struct menu_item_ex name = \

View file

@ -187,7 +187,7 @@ int do_center_band_menu(void* param)
menu.flags = MT_MENU|(3<<MENU_COUNT_SHIFT)|MENU_HAS_DESC;
menu.submenus = band_items[band-1];
menu.callback_and_desc = &cb_and_desc;
do_menu(&menu);
do_menu(&menu, NULL);
return 0;
}
MAKE_MENU(band_0_menu, ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), NULL,

View file

@ -28,12 +28,14 @@ extern const struct menu_item_ex
display_menu, /* display_menu.c */
playback_menu_item, /* playback_menu.c */
#ifdef HAVE_RECORDING
recording_settings_menu, /* recording_menu.c */
recording_settings, /* recording_menu.c */
#endif
sound_settings, /* sound_menu.c */
settings_menu_item, /* settings_menu.c */
playlist_menu_item, /* playlist_menu.c */
equalizer_menu; /* eq_menu.c */
playlist_settings, /* playlist_menu.c */
playlist_options, /* playlist_menu.c */
equalizer_menu, /* eq_menu.c */
info_menu; /* info_menu.c */
#ifdef HAVE_WM8758
extern const struct menu_item_ex hw_eq_menu; /* eq_menu.c */

View file

@ -30,9 +30,6 @@
#include "settings_menu.h"
#include "exported_menus.h"
#include "tree.h"
#if CONFIG_TUNER
#include "radio.h"
#endif
#ifdef HAVE_RECORDING
#include "recording.h"
#endif
@ -49,9 +46,6 @@
#include "logfdisp.h"
#endif
/* lazy coders can use this function if the needed callback
is just to say if the item is shown or not */
int dynamicitem_callback(int action,const struct menu_item_ex *this_item);
struct browse_folder_info {
@ -59,12 +53,11 @@ struct browse_folder_info {
int show_options;
};
static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
static struct browse_folder_info rocks = {PLUGIN_DIR, SHOW_PLUGINS};
static struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG};
static int browse_folder(void *param)
{
const struct browse_folder_info *info =
(const struct browse_folder_info*)param;
(const struct browse_folder_info*)param;
return rockbox_browse(info->dir, info->show_options);
}
@ -384,26 +377,6 @@ MAKE_MENU(info_menu, ID2P(LANG_INFO), 0, bitmap_icons_6x8[Icon_Questionmark],
MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME),
browse_folder, (void*)&theme, NULL, bitmap_icons_6x8[Icon_Folder]);
MENUITEM_FUNCTION_WPARAM(browse_plugins, ID2P(LANG_PLUGINS),
browse_folder, (void*)&rocks, NULL, bitmap_icons_6x8[Icon_Plugin]);
#if CONFIG_TUNER
MENUITEM_FUNCTION(load_radio_screen, ID2P(LANG_FM_RADIO),
(menu_function)radio_screen, dynamicitem_callback,
bitmap_icons_6x8[Icon_Radio_screen]);
#endif
MENUITEM_FUNCTION(mrb_bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
(menu_function)bookmark_mrb_load, NULL, bitmap_icons_6x8[Icon_Bookmark]);
#ifdef HAVE_LCD_CHARCELLS
static int do_shutdown(void)
{
sys_poweroff();
return 0;
}
MENUITEM_FUNCTION(do_shutdown_item, ID2P(LANG_SHUTDOWN), do_shutdown, NULL, NOICON);
#endif
#ifdef HAVE_LCD_CHARCELLS
int mainmenu_callback(int action,const struct menu_item_ex *this_item)
@ -423,42 +396,14 @@ int mainmenu_callback(int action,const struct menu_item_ex *this_item)
#else
#define mainmenu_callback NULL
#endif
/* NOTE: This title will be translatable once we decide what to call this menu
when the root menu comes in... hopefully in the next few days */
MAKE_MENU(main_menu_, "Rockbox Main Menu", mainmenu_callback,
MAKE_MENU(main_menu_, ID2P(LANG_SETTINGS_MENU), mainmenu_callback,
bitmap_icons_6x8[Icon_Submenu_Entered],
&mrb_bookmarks, &sound_settings,
&sound_settings,
&settings_menu_item, &manage_settings, &browse_themes,
#if CONFIG_TUNER
&load_radio_screen,
#endif
#ifdef HAVE_RECORDING
&recording_settings_menu,
#endif
&playlist_menu_item, &browse_plugins, &info_menu
#ifdef HAVE_LCD_CHARCELLS
,&do_shutdown_item
&recording_settings,
#endif
);
/* MAIN MENU */
/***********************************/
/* lazy coders can use this function if the needed
callback is just to say if the item is shown or not */
int dynamicitem_callback(int action,const struct menu_item_ex *this_item)
{
if (action != ACTION_REQUEST_MENUITEM)
return action;
#if CONFIG_TUNER
if (this_item == &load_radio_screen)
{
if (radio_hardware_present() == 0)
return ACTION_EXIT_MENUITEM;
}
#else
(void)this_item;
#endif
return action;
}

View file

@ -57,7 +57,6 @@ int playback_callback(int action,const struct menu_item_ex *this_item);
MENUITEM_SETTING(shuffle_item, &global_settings.playlist_shuffle, playback_callback);
MENUITEM_SETTING(repeat_mode, &global_settings.repeat_mode, playback_callback);
MENUITEM_SETTING(play_selected, &global_settings.play_selected, NULL);
MENUITEM_SETTING(resume, &global_settings.resume, NULL);
MENUITEM_SETTING(ff_rewind_accel, &global_settings.ff_rewind_accel, NULL);
MENUITEM_SETTING(ff_rewind_min_step, &global_settings.ff_rewind_min_step, NULL);
@ -108,7 +107,7 @@ int replaygain_callback(int action,const struct menu_item_ex *this_item)
(void)this_item;
switch (action)
{
case ACTION_EXIT_MENUITEM: /* on exit */
case ACTION_EXIT_MENUITEM: /* on exit */
dsp_set_replaygain();
break;
}
@ -172,7 +171,7 @@ MAKE_MENU(unplug_menu, ID2P(LANG_UNPLUG), 0, NOICON,
MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
bitmap_icons_6x8[Icon_Playback_menu],
&shuffle_item, &repeat_mode, &play_selected, &resume,
&shuffle_item, &repeat_mode, &play_selected,
&ff_rewind_settings_menu,
&buffer_margin, &fade_on_stop, &party_mode,

View file

@ -73,12 +73,14 @@ MENUITEM_FUNCTION(catalog, ID2P(LANG_CATALOG),
MENUITEM_SETTING(recursive_dir_insert, &global_settings.recursive_dir_insert, NULL);
MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL);
MAKE_MENU(playlist_menu_item, ID2P(LANG_PLAYLIST_MENU), NULL,
MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLIST_MENU), NULL,
bitmap_icons_6x8[Icon_Playlist],
&create_playlist_item, &view_playlist, &save_playlist, &catalog,
&recursive_dir_insert, &warn_on_erase);
MAKE_MENU(playlist_options, ID2P(LANG_PLAYLIST_MENU), NULL,
bitmap_icons_6x8[Icon_Playlist],
&create_playlist_item, &view_playlist, &save_playlist, &catalog);
bool playlist_menu(void)
{
return do_menu(&playlist_menu_item);
return do_menu(&playlist_options, NULL);
}

View file

@ -29,14 +29,8 @@
#include "recording.h"
#ifdef HAVE_RECORDING
MENUITEM_FUNCTION(rec_menu_recording_screen_item, ID2P(LANG_RECORDING_MENU),
(menu_function)recording_screen, NULL, NOICON);
/* TEMP */
bool recording_menu(bool no_source); /* from apps/sound_menu.h */
MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_SETTINGS),
(int (*)(void*))recording_menu,0, NULL, NOICON);
MAKE_MENU(recording_settings_menu,ID2P(LANG_RECORDING),
0, bitmap_icons_6x8[Icon_Recording],
&rec_menu_recording_screen_item, &recording_settings);
#endif

View file

@ -281,9 +281,11 @@ MENUITEM_SETTING(line_in, &global_settings.line_in, linein_callback);
#if CONFIG_CHARGING
MENUITEM_SETTING(car_adapter_mode, &global_settings.car_adapter_mode, NULL);
#endif
MENUITEM_SETTING(start_screen, &global_settings.start_in_screen, NULL);
MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
0, bitmap_icons_6x8[Icon_System_menu],
&start_screen,
#ifndef SIMULATOR
&battery_menu,
#endif
@ -385,7 +387,8 @@ MENUITEM_FUNCTION(browse_langs, ID2P(LANG_LANGUAGE), language_browse,
MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0,
bitmap_icons_6x8[Icon_General_settings_menu],
&playback_menu_item, &file_menu, &display_menu, &system_menu,
&playback_menu_item, &playlist_settings, &file_menu,
&display_menu, &system_menu,
&bookmark_settings_menu, &browse_langs, &voice_settings_menu );
/* SETTINGS MENU */
/***********************************/

View file

@ -113,5 +113,5 @@ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, bitmap_icons_6x8[Icon
bool sound_menu(void)
{
return do_menu(&sound_settings);
return do_menu(&sound_settings, 0);
}

View file

@ -1043,7 +1043,7 @@ int onplay(char* file, int attr, int from)
menu_exit(m);
if (exit_to_main)
result = main_menu();
onplay_result = ONPLAY_MAINMENU;
#ifdef HAVE_LCD_BITMAP
if (global_settings.statusbar)

View file

@ -22,7 +22,8 @@
int onplay(char* file, int attr, int from_screen);
enum {
ONPLAY_OK,
ONPLAY_MAINMENU = -1,
ONPLAY_OK = 0,
ONPLAY_RELOAD_DIR,
ONPLAY_START_PLAY
};

View file

@ -79,6 +79,7 @@ const unsigned char bitmap_icons_6x8[][6] =
#endif
{ 0x1f, 0x11, 0x7d, 0x46, 0x44, 0x78 }, /* File View Menu */
{ 0x06, 0x7f, 0x06, 0x18, 0x7f, 0x18 }, /* EQ menu */
{ 0x20, 0x70, 0x70, 0x3f, 0x0a, 0x0a }, /* "rockbox" musical note */
};
const unsigned char bitmap_icons_7x8[][7] =

View file

@ -83,6 +83,7 @@ enum icons_6x8 {
#endif
Icon_file_view_menu,
Icon_EQ,
Icon_Rockbox,
Icon6x8Last,
};

View file

@ -62,6 +62,7 @@
#include "action.h"
#include "list.h"
#include "menus/exported_menus.h"
#include "root_menu.h"
#if CONFIG_TUNER
@ -365,11 +366,12 @@ static void next_preset(int direction)
}
bool radio_screen(void)
int radio_screen(void)
{
char buf[MAX_PATH];
bool done = false;
int button, lastbutton = BUTTON_NONE;
int ret_val = GO_TO_ROOT;
#ifdef FM_RECORD_DBLPRE
unsigned long rec_lastclick = 0;
#endif
@ -582,7 +584,7 @@ bool radio_screen(void)
#endif
keep_playing = true;
done = true;
ret_val = GO_TO_ROOT;
if(presets_changed)
{
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
@ -596,7 +598,7 @@ bool radio_screen(void)
/* Clear the preset list on exit. */
clear_preset_list();
break;
case ACTION_STD_PREV:
@ -1277,7 +1279,7 @@ static int handle_radio_presets(void)
case ACTION_F3:
case ACTION_STD_CONTEXT:
selected_preset = gui_synclist_get_sel_pos(&lists);
do_menu(&handle_radio_preset_menu);
do_menu(&handle_radio_preset_menu, NULL);
break;
default:
if(default_event_handler(action) == SYS_USB_CONNECTED)
@ -1501,7 +1503,7 @@ MAKE_MENU(radio_menu_items, ID2P(LANG_FM_MENU), NULL,
/* main menu of the radio screen */
static bool radio_menu(void)
{
return (bool)do_menu(&radio_menu_items);
return (bool)do_menu(&radio_menu_items, NULL);
}
#endif

View file

@ -26,7 +26,7 @@
#if CONFIG_TUNER
void radio_load_presets(char *filename);
void radio_init(void);
bool radio_screen(void);
int radio_screen(void);
void radio_start(void);
void radio_pause(void);
void radio_stop(void);

361
apps/root_menu.c Normal file
View file

@ -0,0 +1,361 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
*
* Copyright (C) 2007 Jonathan Gordon
*
* 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.
*
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "config.h"
#include "menu.h"
#include "root_menu.h"
#include "lang.h"
#include "settings.h"
#include "kernel.h"
#include "debug.h"
#include "misc.h"
#include "rolo.h"
#include "backdrop.h"
#include "talk.h"
#include "audio.h"
/* gui api */
#include "list.h"
#include "statusbar.h"
#include "splash.h"
#include "buttonbar.h"
#include "textarea.h"
#include "action.h"
#include "yesno.h"
#include "main_menu.h"
#include "tree.h"
#include "radio.h"
#ifdef HAVE_RECORDING
#include "recording.h"
#endif
#include "gwps-common.h"
#include "bookmark.h"
#include "tagtree.h"
#include "menus/exported_menus.h"
struct root_items {
int (*function)(void* param);
void* param;
};
static int last_screen = GO_TO_ROOT; /* unfortunatly needed so we can resume
or goto current track based on previous
screen */
static int browser(void* param)
{
int ret_val;
struct tree_context* tc = tree_get_context();
int filter = SHOW_SUPPORTED;
char folder[MAX_PATH] = "/";
/* stuff needed to remember position in file browser */
static char last_folder[MAX_PATH] = "/";
/* and stuff for the database browser */
static int last_db_dirlevel = 0;
switch ((int)param)
{
case GO_TO_FILEBROWSER:
filter = global_settings.dirfilter;
if (global_settings.browse_current &&
last_screen == GO_TO_WPS && audio_status() &&
wps_state.current_track_path[0] != '\0')
{
snprintf(folder, MAX_PATH, "%s", wps_state.current_track_path);
}
else
snprintf(folder, MAX_PATH, "%s/", last_folder);
break;
case GO_TO_DBBROWSER:
if (!tagcache_is_usable())
{
gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
return GO_TO_PREVIOUS;
}
filter = SHOW_ID3DB;
tc->dirlevel = last_db_dirlevel;
break;
case GO_TO_BROWSEPLUGINS:
filter = SHOW_PLUGINS;
snprintf(folder, MAX_PATH, "%s/", PLUGIN_DIR);
break;
}
ret_val = rockbox_browse(folder, filter);
switch ((int)param)
{
case GO_TO_FILEBROWSER:
strcpy(last_folder, tc->currdir);
break;
case GO_TO_DBBROWSER:
last_db_dirlevel = tc->dirlevel;
break;
}
return ret_val;
}
static int menu(void* param)
{
(void)param;
return main_menu();
}
#ifdef HAVE_RECORDING
static int recscrn(void* param)
{
(void)param;
recording_screen(false);
return GO_TO_ROOT;
}
#endif
static int wpsscrn(void* param)
{
int ret_val = GO_TO_PREVIOUS;
(void)param;
if (audio_status())
{
ret_val = gui_wps_show();
}
else if ( global_status.resume_index != -1 )
{
DEBUGF("Resume index %X offset %X\n",
global_status.resume_index,
global_status.resume_offset);
#ifdef HAVE_ALARM_MOD
if ( rtc_check_alarm_started(true) ) {
rtc_enable_alarm(false);
}
#endif
if (playlist_resume() != -1)
{
playlist_start(global_status.resume_index,
global_status.resume_offset);
ret_val = gui_wps_show();
}
}
else
{
gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
}
#if LCD_DEPTH > 1
show_main_backdrop();
#endif
return ret_val;
}
#if CONFIG_TUNER
static int radio(void* param)
{
(void)param;
radio_screen();
return GO_TO_ROOT;
}
#endif
static int load_bmarks(void* param)
{
(void)param;
bookmark_mrb_load();
return GO_TO_PREVIOUS;
}
static const struct root_items items[] = {
[GO_TO_FILEBROWSER] = { browser, (void*)GO_TO_FILEBROWSER },
[GO_TO_DBBROWSER] = { browser, (void*)GO_TO_DBBROWSER },
[GO_TO_WPS] = { wpsscrn, NULL },
[GO_TO_MAINMENU] = { menu, NULL },
#ifdef HAVE_RECORDING
[GO_TO_RECSCREEN] = { recscrn, NULL },
#endif
#if CONFIG_TUNER
[GO_TO_FM] = { radio, NULL },
#endif
[GO_TO_RECENTBMARKS] = { load_bmarks, NULL },
[GO_TO_BROWSEPLUGINS] = { browser, (void*)GO_TO_BROWSEPLUGINS },
};
static const int nb_items = sizeof(items)/sizeof(*items);
#ifdef BOOTFILE
extern bool boot_changed; /* from tree.c */
static void check_boot(void)
{
if (boot_changed) {
char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)};
struct text_message message={lines, 2};
if(gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
rolo_load("/" BOOTFILE);
boot_changed = false;
}
}
#else
# define check_boot()
#endif
int item_callback(int action, const struct menu_item_ex *this_item) ;
MENUITEM_RETURNVALUE(file_browser, ID2P(LANG_DIR_BROWSER), GO_TO_FILEBROWSER,
NULL, bitmap_icons_6x8[Icon_file_view_menu]);
MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER,
NULL, bitmap_icons_6x8[Icon_Audio]);
MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS,
NULL, bitmap_icons_6x8[Icon_Plugin]);
char *get_wps_item_name(int selected_item, void * data, char *buffer)
{
(void)selected_item; (void)data; (void)buffer;
if (audio_status())
return str(LANG_NOW_PLAYING);
return str(LANG_RESUME_PLAYBACK);
}
MENUITEM_RETURNVALUE_DYNTEXT(wps_item, GO_TO_WPS, NULL, get_wps_item_name,
NULL, bitmap_icons_6x8[Icon_Playback_menu]);
#ifdef HAVE_RECORDING
MENUITEM_RETURNVALUE(rec, ID2P(LANG_RECORDING_MENU), GO_TO_RECSCREEN,
NULL, bitmap_icons_6x8[Icon_Recording]);
#endif
#if CONFIG_TUNER
MENUITEM_RETURNVALUE(fm, ID2P(LANG_FM_RADIO), GO_TO_FM,
item_callback, bitmap_icons_6x8[Icon_Radio_screen]);
#endif
MENUITEM_RETURNVALUE(menu_, ID2P(LANG_SETTINGS_MENU), GO_TO_MAINMENU,
NULL, bitmap_icons_6x8[Icon_Submenu_Entered]);
MENUITEM_RETURNVALUE(bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
GO_TO_RECENTBMARKS, item_callback,
bitmap_icons_6x8[Icon_Bookmark]);
#ifdef HAVE_LCD_CHARCELLS
static int do_shutdown(void)
{
sys_poweroff();
return 0;
}
MENUITEM_FUNCTION(do_shutdown_item, ID2P(LANG_SHUTDOWN), do_shutdown, NULL, NOICON);
#endif
MAKE_MENU(root_menu_, ID2P(LANG_ROCKBOX_TITLE),
NULL, bitmap_icons_6x8[Icon_Rockbox],
&bookmarks, &file_browser, &db_browser,
&wps_item, &menu_,
#ifdef HAVE_RECORDING
&rec,
#endif
#if CONFIG_TUNER
&fm,
#endif
&playlist_options, &rocks_browser, &info_menu
#ifdef HAVE_LCD_CHARCELLS
,&do_shutdown_item
#endif
);
int item_callback(int action, const struct menu_item_ex *this_item)
{
switch (action)
{
case ACTION_REQUEST_MENUITEM:
#if CONFIG_TUNER
if (this_item == &fm)
{
if (radio_hardware_present() == 0)
return ACTION_EXIT_MENUITEM;
}
else
#endif
if (this_item == &bookmarks)
{
if (global_settings.usemrb == 0)
return ACTION_EXIT_MENUITEM;
}
break;
}
return action;
}
void root_menu(void)
{
int previous_browser = GO_TO_FILEBROWSER;
int previous_music = GO_TO_WPS;
int ret_val = GO_TO_ROOT;
int this_screen = GO_TO_ROOT;
int selected = 0;
if (global_settings.start_in_screen == 0)
ret_val = (int)global_status.last_screen;
else ret_val = global_settings.start_in_screen - 2;
while (true)
{
switch (ret_val)
{
case GO_TO_ROOT:
ret_val = do_menu(&root_menu_, &selected);
/* As long as MENU_ATTACHED_USB == GO_TO_ROOT this works */
if (ret_val == MENU_ATTACHED_USB)
{
check_boot();
continue;
}
if (ret_val == GO_TO_PREVIOUS_MUSIC)
ret_val = previous_music;
last_screen = GO_TO_ROOT;
break;
case GO_TO_PREVIOUS:
ret_val = last_screen;
if (last_screen == GO_TO_ROOT)
continue;
break;
case GO_TO_PREVIOUS_BROWSER:
if ((previous_browser == GO_TO_DBBROWSER) &&
!tagcache_is_usable())
ret_val = GO_TO_FILEBROWSER;
else
ret_val = previous_browser;
break;
case GO_TO_PREVIOUS_MUSIC:
ret_val = previous_music;
break;
}
this_screen = ret_val;
if (this_screen == GO_TO_FILEBROWSER)
previous_browser = GO_TO_FILEBROWSER;
else if (this_screen == GO_TO_DBBROWSER)
previous_browser = GO_TO_DBBROWSER;
else if (this_screen == GO_TO_WPS)
previous_music = GO_TO_WPS;
#if CONFIG_TUNER
else if (this_screen == GO_TO_FM)
previous_music = GO_TO_FM;
#endif
/* set the global_status.last_screen before entering,
if we dont we will always return to the wrong screen on boot */
global_status.last_screen = (char)this_screen;
status_save();
action_signalscreenchange();
ret_val = items[this_screen].function(items[this_screen].param);
if (ret_val != GO_TO_PREVIOUS)
last_screen = this_screen;
}
return;
}

44
apps/root_menu.h Normal file
View file

@ -0,0 +1,44 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
*
* Copyright (C) 2007 Jonathan Gordon
*
* 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.
*
****************************************************************************/
#include "config.h"
void root_menu(void);
enum {
GO_TO_PREVIOUS_MUSIC = -4,
GO_TO_PREVIOUS_BROWSER = -3,
GO_TO_PREVIOUS = -2,
GO_TO_ROOT = -1,
GO_TO_FILEBROWSER = 0,
GO_TO_DBBROWSER,
GO_TO_WPS,
GO_TO_MAINMENU,
#ifdef HAVE_RECORDING
GO_TO_RECSCREEN,
#endif
#ifdef CONFIG_TUNER
GO_TO_FM,
#endif
GO_TO_RECENTBMARKS,
GO_TO_BROWSEPLUGINS,
/* Do Not add any items above here unless you want it to be able to
be the "start screen" after a boot up. The setting in settings_list.c
will need editing if this is the case. */
};
extern const struct menu_item_ex root_menu_;

View file

@ -654,9 +654,6 @@ bool quick_screen_quick(int button_enter)
[SHOW_SUPPORTED]={ STR(LANG_SYSFONT_FILTER_SUPPORTED) },
[SHOW_MUSIC]={ STR(LANG_SYSFONT_FILTER_MUSIC) },
[SHOW_PLAYLIST]={ STR(LANG_SYSFONT_FILTER_PLAYLIST) },
#ifdef HAVE_TAGCACHE
[SHOW_ID3DB]={ STR(LANG_SYSFONT_FILTER_ID3DB) }
#endif
};
static const struct opt_items right_items[] = {
[REPEAT_OFF]={ STR(LANG_SYSFONT_OFF) },

View file

@ -277,6 +277,7 @@ struct system_status
int last_frequency; /* Last frequency for resuming, in FREQ_STEP units,
relative to MIN_FREQ */
#endif
char last_screen;
};
struct user_settings
@ -684,6 +685,7 @@ struct user_settings
/* Encoder Settings End */
#endif /* CONFIG_CODEC == SWCODEC */
bool cuesheet;
int start_in_screen;
};
/** global variables **/

View file

@ -617,15 +617,8 @@ const struct settings_list settings[] = {
#endif /* HAVE_MMC */
/* browser */
CHOICE_SETTING(0, dirfilter, LANG_FILTER, SHOW_SUPPORTED, "show files",
#ifndef HAVE_TAGCACHE
"all,supported,music,playlists", NULL, 4, ID2P(LANG_FILTER_ALL),
ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST)
#else
"all,supported,music,playlists,id3 database", NULL, 5, ID2P(LANG_FILTER_ALL),
ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC),
ID2P(LANG_FILTER_PLAYLIST), ID2P(LANG_FILTER_ID3DB)
#endif
),
ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST)),
OFFON_SETTING(0,sort_case,LANG_SORT_CASE,false,"sort case",NULL),
OFFON_SETTING(0,browse_current,LANG_FOLLOW,false,"follow playlist",NULL),
OFFON_SETTING(0,playlist_viewer_icons,LANG_SHOW_ICONS,true,
@ -1089,6 +1082,34 @@ const struct settings_list settings[] = {
#endif
#endif
OFFON_SETTING(0,cuesheet,LANG_CUESHEET_ENABLE,false,"cuesheet support", NULL),
CHOICE_SETTING(0, start_in_screen, LANG_START_SCREEN, 1,
"start in screen", "previous,root,files,db,wps,menu,"
#ifdef HAVE_RECORDING
",recording"
#endif
#if CONFIG_TUNER
",radio"
#endif
,NULL,
#if defined(HAVE_RECORDING) && CONFIG_TUNER
8,
#elif defined(HAVE_RECORDING) || CONFIG_TUNER /* only one of them */
7,
#else
6,
#endif
ID2P(LANG_PREVIOUS_SCREEN), ID2P(LANG_MAIN_MENU),
ID2P(LANG_DIR_BROWSER), ID2P(LANG_TAGCACHE),
ID2P(LANG_RESUME_PLAYBACK), ID2P(LANG_SETTINGS_MENU)
#ifdef HAVE_RECORDING
,ID2P(LANG_RECORDING)
#endif
#if CONFIG_TUNER
,ID2P(LANG_FM_RADIO)
#endif
),
SYSTEM_SETTING(NVRAM(1),last_screen,-1),
};
const int nb_settings = sizeof(settings)/sizeof(*settings);

View file

@ -424,12 +424,6 @@ static bool recdirectory(void)
names, 2, NULL );
}
static bool reconstartup(void)
{
return set_bool(str(LANG_RECORD_STARTUP),
&global_settings.rec_startup);
}
#if CONFIG_BACKLIGHT
static bool cliplight(void)
{
@ -940,7 +934,6 @@ bool recording_menu(bool no_source)
{ ID2P(LANG_RECORD_TIMESPLIT), filesplitoptionsmenu },
{ ID2P(LANG_RECORD_PRERECORD_TIME), recprerecord },
{ ID2P(LANG_RECORD_DIRECTORY), recdirectory },
{ ID2P(LANG_RECORD_STARTUP), reconstartup },
#if CONFIG_BACKLIGHT
{ ID2P(LANG_CLIP_LIGHT), cliplight },
#endif

View file

@ -3953,7 +3953,10 @@ bool tagcache_is_initialized(void)
{
return tc_stat.initialized;
}
bool tagcache_is_usable(void)
{
return tc_stat.initialized && tc_stat.ready;
}
int tagcache_get_commit_step(void)
{
return tc_stat.commit_step;

View file

@ -182,6 +182,7 @@ void tagcache_unload_ramcache(void);
#endif
void tagcache_init(void);
bool tagcache_is_initialized(void);
bool tagcache_is_usable(void);
void tagcache_start_scan(void);
void tagcache_stop_scan(void);
bool tagcache_update(void);

View file

@ -79,6 +79,7 @@
#include "textarea.h"
#include "action.h"
#include "root_menu.h"
#if LCD_DEPTH > 1
#include "backdrop.h"
@ -160,9 +161,10 @@ static int max_files = 0;
static bool reload_dir = false;
static bool start_wps = false;
static bool dirbrowse(void);
static int curr_context = false;/* id3db or tree*/
int dirbrowse(void);
/*
* removes the extension of filename (if it doesn't start with a .)
* puts the result in buffer
@ -272,13 +274,8 @@ void browse_root(void)
gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1);
gui_synclist_set_icon_callback(&tree_lists,
global_settings.show_icons?&tree_get_fileicon:NULL);
#ifndef SIMULATOR
dirbrowse();
#else
if (!dirbrowse()) {
DEBUGF("No filesystem found. Have you forgotten to create it?\n");
}
#endif
/* not the best place for this call... but... */
root_menu();
}
void tree_get_filetypes(const struct filetype** types, int* count)
@ -478,54 +475,6 @@ void reload_directory(void)
reload_dir = true;
}
static void start_resume(bool just_powered_on)
{
bool do_resume = false;
if ( global_status.resume_index != -1 ) {
DEBUGF("Resume index %X offset %X\n",
global_status.resume_index,
global_status.resume_offset);
#ifdef HAVE_RTC_ALARM
if ( rtc_check_alarm_started(true) ) {
rtc_enable_alarm(false);
do_resume = true;
}
#endif
/* always resume? */
if ( global_settings.resume || ! just_powered_on)
#ifdef HAVE_HEADPHONE_DETECTION
{
if ( just_powered_on )
{
if ( !global_settings.unplug_autoresume
|| headphones_inserted() )
do_resume = true;
}
else
do_resume = true;
}
#else
do_resume = true;
#endif
if (! do_resume) return;
if (playlist_resume() != -1)
{
playlist_start(global_status.resume_index,
global_status.resume_offset);
start_wps = true;
}
else return;
}
else if (! just_powered_on) {
gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
}
}
/* Selects a file and update tree context properly */
void set_current_file(char *path)
{
@ -568,10 +517,7 @@ void set_current_file(char *path)
tc.selected_item_history[tc.dirlevel] = -1;
/* use '/' to calculate dirlevel */
/* FIXME : strlen(path) : crazy oO better to store it at
the beginning */
int path_len = strlen(path) + 1;
for (i = 1; i < path_len; i++)
for (i = 1; path[i] != '\0'; i++)
{
if (path[i] == '/')
{
@ -580,9 +526,13 @@ void set_current_file(char *path)
}
}
}
if (ft_load(&tc, NULL) >= 0)
{
tc.selected_item = tree_get_file_position(lastfile);
}
}
#ifdef HAVE_TAGCACHE
#if defined(HAVE_TAGCACHE) && defined(HAVE_QUICKSCREEN)
static bool check_changed_id3mode(bool currmode)
{
if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) {
@ -605,7 +555,7 @@ static bool check_changed_id3mode(bool currmode)
#endif
/* main loop, handles key events */
static bool dirbrowse(void)
int dirbrowse()
{
int numentries=0;
char buf[MAX_PATH];
@ -627,8 +577,8 @@ static bool dirbrowse(void)
else
#endif
curr_context=CONTEXT_TREE;
tc.selected_item = 0;
tc.dirlevel=0;
if (tc.selected_item < 0)
tc.selected_item = 0;
#ifdef HAVE_TAGCACHE
tc.firstpos=0;
lasttable = -1;
@ -636,43 +586,22 @@ static bool dirbrowse(void)
lastfirstpos = 0;
#endif
if (*tc.dirfilter < NUM_FILTER_MODES) {
#ifdef HAVE_RECORDING
#ifndef SIMULATOR
if (global_settings.rec_startup) {
/* We fake being in the menu structure by calling
the appropriate parent when we drop out of each screen */
#if CONFIG_CODEC == SWCODEC
/* Put in a 1 sec pause to slow bootup or the recording codecs
won't initialize */
sleep(HZ);
#endif
recording_screen(false);
rec_menu();
main_menu();
}
else
#endif
#endif
start_resume(true);
start_wps = false;
numentries = update_dir();
if (numentries == -1)
return false; /* currdir is not a directory */
if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0)
{
gui_syncsplash(HZ*2, true, str(LANG_NO_FILES));
return false; /* No files found for rockbox_browser() */
}
/* If we don't need to show the wps, draw the dir */
if (!start_wps) {
numentries = update_dir();
if (numentries == -1)
return false; /* currdir is not a directory */
if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0)
{
gui_syncsplash(HZ*2, true, str(LANG_NO_FILES));
return false; /* No files found for rockbox_browser() */
}
}
while(1) {
struct entry *dircache = tc.dircache;
bool restore = false;
if (tc.dirlevel < 0)
tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
#ifdef BOOTFILE
if (boot_changed) {
char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)};
@ -715,10 +644,12 @@ static bool dirbrowse(void)
exit_func = true;
break;
}
/* if we are in /, nothing to do */
if (tc.dirlevel == 0 && !strcmp(currdir,"/"))
break;
if ((*tc.dirfilter == SHOW_ID3DB && tc.dirlevel == 0) ||
((*tc.dirfilter != SHOW_ID3DB && !strcmp(currdir,"/"))))
{
break; /* do nothing */
}
#ifdef HAVE_TAGCACHE
if (id3db)
tagtree_exit(&tc);
@ -772,37 +703,17 @@ static bool dirbrowse(void)
/* don't enter menu from plugin browser */
if (*tc.dirfilter < NUM_FILTER_MODES)
{
int i;
FOR_NB_SCREENS(i)
screens[i].stop_scroll();
action_signalscreenchange();
if (main_menu())
reload_dir = true;
restore = true;
#ifdef HAVE_TAGCACHE
id3db = check_changed_id3mode(id3db);
if(id3db)
reload_dir = true;
#endif
return GO_TO_ROOT;
}
else /* use it as a quick exit instead */
exit_func = true;
return GO_TO_PREVIOUS;
break;
case ACTION_TREE_WPS:
/* don't enter wps from plugin browser etc */
if (*tc.dirfilter < NUM_FILTER_MODES)
{
if (audio_status() & AUDIO_STATUS_PLAY)
{
start_wps=true;
}
else
{
start_resume(false);
restore = true;
}
return GO_TO_PREVIOUS_MUSIC;
}
break;
#ifdef HAVE_QUICKSCREEN
@ -869,6 +780,9 @@ static bool dirbrowse(void)
}
switch (onplay_result)
{
case ONPLAY_MAINMENU:
return GO_TO_ROOT;
case ONPLAY_OK:
restore = true;
break;
@ -878,7 +792,7 @@ static bool dirbrowse(void)
break;
case ONPLAY_START_PLAY:
start_wps = true;
return GO_TO_WPS;
break;
}
break;
@ -952,37 +866,13 @@ static bool dirbrowse(void)
}
break;
}
if (start_wps)
return GO_TO_WPS;
if ( button )
{
ata_spin();
}
if (start_wps && audio_status() )
{
int i;
FOR_NB_SCREENS(i)
screens[i].stop_scroll();
if (gui_wps_show() == SYS_USB_CONNECTED)
reload_dir = true;
#ifdef HAVE_HOTSWAP
else
#ifdef HAVE_TAGCACHE
if (!id3db) /* Try reload to catch 'no longer valid' case. */
#endif
reload_dir = true;
#endif
#if LCD_DEPTH > 1
show_main_backdrop();
#endif
#ifdef HAVE_TAGCACHE
id3db = check_changed_id3mode(id3db);
#endif
restore = true;
start_wps=false;
}
check_rescan:
/* do we need to rescan dir? */
@ -1016,7 +906,7 @@ static bool dirbrowse(void)
}
if (exit_func)
break;
return GO_TO_PREVIOUS;
if (restore || reload_dir) {
/* restore display */
@ -1252,24 +1142,39 @@ bool create_playlist(void)
return true;
}
bool rockbox_browse(const char *root, int dirfilter)
int rockbox_browse(const char *root, int dirfilter)
{
static struct tree_context backup;
int last_context;
backup = tc;
reload_dir = true;
memcpy(tc.currdir, root, sizeof(tc.currdir));
start_wps = false;
int ret_val = 0;
int *last_filter = tc.dirfilter;
tc.dirfilter = &dirfilter;
last_context = curr_context;
dirbrowse();
tc = backup;
curr_context = last_context;
return false;
reload_dir = true;
if (dirfilter >= NUM_FILTER_MODES)
{
static struct tree_context backup;
int last_context;
backup = tc;
tc.dirlevel = 0;
memcpy(tc.currdir, root, sizeof(tc.currdir));
start_wps = false;
last_context = curr_context;
ret_val = dirbrowse();
tc = backup;
curr_context = last_context;
}
else
{
static char buf[MAX_PATH];
if (dirfilter != SHOW_ID3DB)
tc.dirfilter = &global_settings.dirfilter;
strcpy(buf,root);
set_current_file(buf);
ret_val = dirbrowse();
}
tc.dirfilter = last_filter;
return ret_val;
}
void tree_init(void)

View file

@ -101,7 +101,7 @@ void tree_get_filetypes(const struct filetype**, int*);
void tree_init(void);
void browse_root(void);
void set_current_file(char *path);
bool rockbox_browse(const char *root, int dirfilter);
int rockbox_browse(const char *root, int dirfilter);
bool create_playlist(void);
void resume_directory(const char *dir);
char *getcwd(char *buf, int size);