summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-03-01 11:14:46 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-03-01 11:14:46 +0000
commit91cb68a1fb5b019aaebf77fae6506bb807059b65 (patch)
treeea3e56a915479ecad597cc0769ca24c2e2bcf686
parentd94c7d3f7679789cce916d213b39f3b54dc0216b (diff)
downloadrockbox-91cb68a1fb5b019aaebf77fae6506bb807059b65.tar.gz
rockbox-91cb68a1fb5b019aaebf77fae6506bb807059b65.zip
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
-rw-r--r--apps/SOURCES1
-rw-r--r--apps/action.h1
-rw-r--r--apps/gui/gwps.c53
-rw-r--r--apps/keymaps/keymap-e200.c9
-rw-r--r--apps/keymaps/keymap-gigabeat.c12
-rw-r--r--apps/keymaps/keymap-h10.c9
-rw-r--r--apps/keymaps/keymap-h1x0_h3x0.c20
-rw-r--r--apps/keymaps/keymap-ipod.c9
-rw-r--r--apps/keymaps/keymap-ondio.c10
-rw-r--r--apps/keymaps/keymap-player.c9
-rw-r--r--apps/keymaps/keymap-recorder.c10
-rw-r--r--apps/keymaps/keymap-x5.c2
-rw-r--r--apps/lang/english.lang136
-rw-r--r--apps/main_menu.c3
-rw-r--r--apps/main_menu.h2
-rw-r--r--apps/menu.c71
-rw-r--r--apps/menu.h39
-rw-r--r--apps/menus/eq_menu.c2
-rw-r--r--apps/menus/exported_menus.h8
-rw-r--r--apps/menus/main_menu.c63
-rw-r--r--apps/menus/playback_menu.c5
-rw-r--r--apps/menus/playlist_menu.c8
-rw-r--r--apps/menus/recording_menu.c6
-rw-r--r--apps/menus/settings_menu.c5
-rw-r--r--apps/menus/sound_menu.c2
-rw-r--r--apps/onplay.c2
-rw-r--r--apps/onplay.h3
-rw-r--r--apps/recorder/icons.c1
-rw-r--r--apps/recorder/icons.h1
-rw-r--r--apps/recorder/radio.c12
-rw-r--r--apps/recorder/radio.h2
-rw-r--r--apps/root_menu.c361
-rw-r--r--apps/root_menu.h44
-rw-r--r--apps/screens.c3
-rw-r--r--apps/settings.h2
-rw-r--r--apps/settings_list.c37
-rw-r--r--apps/sound_menu.c7
-rw-r--r--apps/tagcache.c5
-rw-r--r--apps/tagcache.h1
-rw-r--r--apps/tree.c237
-rw-r--r--apps/tree.h2
41 files changed, 852 insertions, 363 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 83f41cda3a..04199cd1fb 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -29,6 +29,7 @@ playlist.c
29playlist_catalog.c 29playlist_catalog.c
30playlist_viewer.c 30playlist_viewer.c
31plugin.c 31plugin.c
32root_menu.c
32screens.c 33screens.c
33settings.c 34settings.c
34settings_list.c 35settings_list.c
diff --git a/apps/action.h b/apps/action.h
index a1d54b22d8..c1026d8885 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -160,6 +160,7 @@ enum {
160 once the subitem returns */ 160 once the subitem returns */
161 ACTION_ENTER_MENUITEM, 161 ACTION_ENTER_MENUITEM,
162 ACTION_MENU_WPS, 162 ACTION_MENU_WPS,
163 ACTION_MENU_STOP,
163 164
164 /* id3db */ 165 /* id3db */
165 166
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 00290a8871..a5e1e26e0c 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -59,6 +59,7 @@
59#include "backdrop.h" 59#include "backdrop.h"
60#endif 60#endif
61#include "ata_idle_notify.h" 61#include "ata_idle_notify.h"
62#include "root_menu.h"
62 63
63#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" 64#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
64#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps" 65#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
@@ -238,7 +239,9 @@ long gui_wps_show(void)
238 show_main_backdrop(); 239 show_main_backdrop();
239#endif 240#endif
240 action_signalscreenchange(); 241 action_signalscreenchange();
241 onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS); 242 if (onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS)
243 == ONPLAY_MAINMENU)
244 return GO_TO_ROOT;
242#if LCD_DEPTH > 1 245#if LCD_DEPTH > 1
243 show_wps_backdrop(); 246 show_wps_backdrop();
244#endif 247#endif
@@ -258,13 +261,8 @@ long gui_wps_show(void)
258#endif 261#endif
259 FOR_NB_SCREENS(i) 262 FOR_NB_SCREENS(i)
260 gui_wps[i].display->stop_scroll(); 263 gui_wps[i].display->stop_scroll();
261
262 /* set dir browser to current playing song */
263 if (global_settings.browse_current &&
264 wps_state.current_track_path[0] != '\0')
265 set_current_file(wps_state.current_track_path);
266 action_signalscreenchange(); 264 action_signalscreenchange();
267 return 0; 265 return GO_TO_PREVIOUS_BROWSER;
268 break; 266 break;
269 267
270 /* play/pause */ 268 /* play/pause */
@@ -497,23 +495,7 @@ long gui_wps_show(void)
497 case ACTION_WPS_MENU: 495 case ACTION_WPS_MENU:
498 FOR_NB_SCREENS(i) 496 FOR_NB_SCREENS(i)
499 gui_wps[i].display->stop_scroll(); 497 gui_wps[i].display->stop_scroll();
500 498 return GO_TO_ROOT;
501#if LCD_DEPTH > 1
502 show_main_backdrop();
503#endif
504 action_signalscreenchange();
505 if (main_menu())
506 return true;
507#if LCD_DEPTH > 1
508 show_wps_backdrop();
509#endif
510#ifdef HAVE_LCD_BITMAP
511 FOR_NB_SCREENS(i)
512 {
513 gui_wps_set_margin(&gui_wps[i]);
514 }
515#endif
516 restore = true;
517 break; 499 break;
518 500
519 501
@@ -639,12 +621,7 @@ long gui_wps_show(void)
639 } 621 }
640 if (update_failed) 622 if (update_failed)
641 { 623 {
642 /* set dir browser to current playing song */ 624 return GO_TO_ROOT;
643 if (global_settings.browse_current &&
644 wps_state.current_track_path[0] != '\0')
645 set_current_file(wps_state.current_track_path);
646
647 return 0;
648 } 625 }
649 update_track = false; 626 update_track = false;
650 } 627 }
@@ -666,12 +643,7 @@ long gui_wps_show(void)
666 ab_reset_markers(); 643 ab_reset_markers();
667#endif 644#endif
668 645
669 /* set dir browser to current playing song */ 646 return GO_TO_PREVIOUS;
670 if (global_settings.browse_current &&
671 wps_state.current_track_path[0] != '\0')
672 set_current_file(wps_state.current_track_path);
673
674 return 0;
675 } 647 }
676 648
677 if ( button ) 649 if ( button )
@@ -685,12 +657,7 @@ long gui_wps_show(void)
685 restoretimer = 0; 657 restoretimer = 0;
686 if (gui_wps_display()) 658 if (gui_wps_display())
687 { 659 {
688 /* set dir browser to current playing song */ 660 return GO_TO_ROOT;
689 if (global_settings.browse_current &&
690 wps_state.current_track_path[0] != '\0')
691 set_current_file(wps_state.current_track_path);
692
693 return 0;
694 } 661 }
695 662
696 if (wps_state.id3){ 663 if (wps_state.id3){
@@ -699,7 +666,7 @@ long gui_wps_show(void)
699 } 666 }
700 } 667 }
701 } 668 }
702 return 0; /* unreachable - just to reduce compiler warnings */ 669 return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
703} 670}
704 671
705/* needs checking if needed end*/ 672/* needs checking if needed end*/
diff --git a/apps/keymaps/keymap-e200.c b/apps/keymaps/keymap-e200.c
index a990e9cd1b..932613d5f2 100644
--- a/apps/keymaps/keymap-e200.c
+++ b/apps/keymaps/keymap-e200.c
@@ -48,6 +48,12 @@ static const struct button_mapping button_context_standard[] = {
48 LAST_ITEM_IN_LIST 48 LAST_ITEM_IN_LIST
49}; /* button_context_standard */ 49}; /* button_context_standard */
50 50
51static const struct button_mapping button_context_menu[] = {
52 { ACTION_MENU_WPS, BUTTON_UP, BUTTON_NONE },
53
54 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
55}; /* button_context_menu */
56
51static const struct button_mapping button_context_wps[] = { 57static const struct button_mapping button_context_wps[] = {
52 { ACTION_WPS_PLAY, BUTTON_UP|BUTTON_REL, BUTTON_UP }, 58 { ACTION_WPS_PLAY, BUTTON_UP|BUTTON_REL, BUTTON_UP },
53 { ACTION_WPS_STOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP }, 59 { ACTION_WPS_STOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP },
@@ -228,8 +234,9 @@ const struct button_mapping* get_context_mapping(int context)
228 switch (context) 234 switch (context)
229 { 235 {
230 case CONTEXT_STD: 236 case CONTEXT_STD:
231 case CONTEXT_MAINMENU:
232 return button_context_standard; 237 return button_context_standard;
238 case CONTEXT_MAINMENU:
239 return button_context_menu;
233 240
234 case CONTEXT_WPS: 241 case CONTEXT_WPS:
235 return button_context_wps; 242 return button_context_wps;
diff --git a/apps/keymaps/keymap-gigabeat.c b/apps/keymaps/keymap-gigabeat.c
index 3f4f8b6ac9..1917714b1e 100644
--- a/apps/keymaps/keymap-gigabeat.c
+++ b/apps/keymaps/keymap-gigabeat.c
@@ -116,6 +116,15 @@ static const struct button_mapping button_context_tree[] = {
116 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST) 116 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
117}; /* button_context_tree */ 117}; /* button_context_tree */
118 118
119static const struct button_mapping button_context_menu[] = {
120 { ACTION_MENU_WPS, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
121 { ACTION_MENU_STOP, BUTTON_A, BUTTON_NONE },
122 { ACTION_MENU_STOP, BUTTON_A|BUTTON_REL, BUTTON_A },
123 { ACTION_MENU_STOP, BUTTON_A|BUTTON_REPEAT, BUTTON_NONE },
124
125 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
126}; /* button_context_tree */
127
119static const struct button_mapping button_context_listtree_scroll_with_combo[] = { 128static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
120 { ACTION_NONE, BUTTON_POWER, BUTTON_NONE }, 129 { ACTION_NONE, BUTTON_POWER, BUTTON_NONE },
121 { ACTION_TREE_PGLEFT, BUTTON_POWER|BUTTON_LEFT, BUTTON_POWER }, 130 { ACTION_TREE_PGLEFT, BUTTON_POWER|BUTTON_LEFT, BUTTON_POWER },
@@ -259,8 +268,9 @@ const struct button_mapping* get_context_mapping(int context)
259 switch (context) 268 switch (context)
260 { 269 {
261 case CONTEXT_STD: 270 case CONTEXT_STD:
262 case CONTEXT_MAINMENU:
263 return button_context_standard; 271 return button_context_standard;
272 case CONTEXT_MAINMENU:
273 return button_context_menu;
264 case CONTEXT_WPS: 274 case CONTEXT_WPS:
265 return button_context_wps; 275 return button_context_wps;
266 276
diff --git a/apps/keymaps/keymap-h10.c b/apps/keymaps/keymap-h10.c
index 904b8c0bbe..c0e5614fcd 100644
--- a/apps/keymaps/keymap-h10.c
+++ b/apps/keymaps/keymap-h10.c
@@ -62,6 +62,12 @@ static const struct button_mapping remote_button_context_standard[] = {
62 LAST_ITEM_IN_LIST 62 LAST_ITEM_IN_LIST
63}; /* remote_button_context_standard */ 63}; /* remote_button_context_standard */
64 64
65static const struct button_mapping button_context_menu[] = {
66 { ACTION_MENU_WPS, BUTTON_PLAY, BUTTON_NONE },
67
68 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
69}; /* button_context_menu */
70
65static const struct button_mapping button_context_wps[] = { 71static const struct button_mapping button_context_wps[] = {
66 { ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY }, 72 { ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
67 { ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT,BUTTON_PLAY }, 73 { ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT,BUTTON_PLAY },
@@ -351,8 +357,9 @@ const struct button_mapping* get_context_mapping(int context)
351 switch (context) 357 switch (context)
352 { 358 {
353 case CONTEXT_STD: 359 case CONTEXT_STD:
354 case CONTEXT_MAINMENU:
355 return button_context_standard; 360 return button_context_standard;
361 case CONTEXT_MAINMENU:
362 return button_context_menu;
356 363
357 case CONTEXT_WPS: 364 case CONTEXT_WPS:
358 return button_context_wps; 365 return button_context_wps;
diff --git a/apps/keymaps/keymap-h1x0_h3x0.c b/apps/keymaps/keymap-h1x0_h3x0.c
index b379081efe..7997270a3b 100644
--- a/apps/keymaps/keymap-h1x0_h3x0.c
+++ b/apps/keymaps/keymap-h1x0_h3x0.c
@@ -65,6 +65,12 @@ static const struct button_mapping button_context_standard[] = {
65 LAST_ITEM_IN_LIST 65 LAST_ITEM_IN_LIST
66}; /* button_context_standard */ 66}; /* button_context_standard */
67 67
68static const struct button_mapping button_context_menu[] = {
69 { ACTION_MENU_WPS, BUTTON_ON, BUTTON_NONE },
70 { ACTION_MENU_STOP, BUTTON_OFF, BUTTON_NONE },
71
72 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
73}; /* button_context_menu */
68 74
69static const struct button_mapping button_context_wps[] = { 75static const struct button_mapping button_context_wps[] = {
70 { ACTION_WPS_PLAY, BUTTON_ON|BUTTON_REL, BUTTON_ON }, 76 { ACTION_WPS_PLAY, BUTTON_ON|BUTTON_REL, BUTTON_ON },
@@ -715,10 +721,18 @@ static const struct button_mapping button_context_radio_h300lcdremote[] = {
715 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) 721 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
716}; 722};
717 723
724static const struct button_mapping button_context_menu_remote[] = {
725 { ACTION_MENU_STOP, BUTTON_RC_STOP, BUTTON_NONE },
726 { ACTION_MENU_WPS, BUTTON_RC_ON, BUTTON_NONE },
727
728 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
729};
730
718/* the actual used tables */ 731/* the actual used tables */
719static const struct button_mapping 732static const struct button_mapping
720 *remote_btn_ctxt_std = 0, 733 *remote_btn_ctxt_std = 0,
721 *remote_btn_ctxt_wps = 0, 734 *remote_btn_ctxt_wps = 0,
735 *remote_btn_ctxt_menu = button_context_menu_remote,
722 *remote_btn_ctxt_list = 0, 736 *remote_btn_ctxt_list = 0,
723 *remote_btn_ctxt_tree = 0, 737 *remote_btn_ctxt_tree = 0,
724 *remote_btn_ctxt_listtree_scroll_w_cmb = 0, 738 *remote_btn_ctxt_listtree_scroll_w_cmb = 0,
@@ -866,8 +880,9 @@ static const struct button_mapping* get_context_mapping_remote(int context)
866 switch (context) 880 switch (context)
867 { 881 {
868 case CONTEXT_STD: 882 case CONTEXT_STD:
869 case CONTEXT_MAINMENU:
870 return remote_btn_ctxt_std; 883 return remote_btn_ctxt_std;
884 case CONTEXT_MAINMENU:
885 return remote_btn_ctxt_menu;
871 case CONTEXT_WPS: /* common for all remotes */ 886 case CONTEXT_WPS: /* common for all remotes */
872 return button_context_wps_remotescommon; 887 return button_context_wps_remotescommon;
873 888
@@ -914,8 +929,9 @@ const struct button_mapping* get_context_mapping(int context)
914 switch (context) 929 switch (context)
915 { 930 {
916 case CONTEXT_STD: 931 case CONTEXT_STD:
917 case CONTEXT_MAINMENU:
918 return button_context_standard; 932 return button_context_standard;
933 case CONTEXT_MAINMENU:
934 return button_context_menu;
919 case CONTEXT_WPS: 935 case CONTEXT_WPS:
920 return button_context_wps; 936 return button_context_wps;
921 937
diff --git a/apps/keymaps/keymap-ipod.c b/apps/keymaps/keymap-ipod.c
index 94dd94333d..8b08f0cbd4 100644
--- a/apps/keymaps/keymap-ipod.c
+++ b/apps/keymaps/keymap-ipod.c
@@ -60,6 +60,12 @@ static const struct button_mapping button_context_tree[] = {
60 60
61 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 61 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
62}; /* button_context_tree */ 62}; /* button_context_tree */
63static const struct button_mapping button_context_menu[] = {
64 { ACTION_MENU_WPS, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
65 { ACTION_MENU_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
66
67 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
68}; /* button_context_menu */
63 69
64static const struct button_mapping button_context_tree_scroll_lr[] = { 70static const struct button_mapping button_context_tree_scroll_lr[] = {
65 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE }, 71 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
@@ -191,8 +197,9 @@ const struct button_mapping* get_context_mapping(int context)
191 return button_context_tree; 197 return button_context_tree;
192 198
193 case CONTEXT_LIST: 199 case CONTEXT_LIST:
194 case CONTEXT_MAINMENU:
195 return button_context_standard; 200 return button_context_standard;
201 case CONTEXT_MAINMENU:
202 return button_context_menu;
196 203
197 case CONTEXT_SETTINGS_EQ: 204 case CONTEXT_SETTINGS_EQ:
198 case CONTEXT_SETTINGS_COLOURCHOOSER: 205 case CONTEXT_SETTINGS_COLOURCHOOSER:
diff --git a/apps/keymaps/keymap-ondio.c b/apps/keymaps/keymap-ondio.c
index 401742b363..17b7fe4aba 100644
--- a/apps/keymaps/keymap-ondio.c
+++ b/apps/keymaps/keymap-ondio.c
@@ -83,10 +83,17 @@ static const struct button_mapping button_context_settings[] = {
83static const struct button_mapping button_context_tree[] = { 83static const struct button_mapping button_context_tree[] = {
84 { ACTION_TREE_WPS, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, 84 { ACTION_TREE_WPS, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
85 { ACTION_TREE_STOP, BUTTON_OFF, BUTTON_NONE }, 85 { ACTION_TREE_STOP, BUTTON_OFF, BUTTON_NONE },
86 { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
86 87
87 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 88 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
88}; /* button_context_listtree */ 89}; /* button_context_listtree */
89 90
91static const struct button_mapping button_context_menu[] = {
92 { ACTION_MENU_WPS, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
93
94 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
95}; /* button_context_menu */
96
90static const struct button_mapping button_context_tree_scroll_lr[] = { 97static const struct button_mapping button_context_tree_scroll_lr[] = {
91 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE }, 98 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
92 { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, 99 { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
@@ -211,8 +218,9 @@ const struct button_mapping* get_context_mapping( int context )
211 case CONTEXT_FM: 218 case CONTEXT_FM:
212 return button_context_radio; 219 return button_context_radio;
213#endif 220#endif
214 case CONTEXT_LIST:
215 case CONTEXT_MAINMENU: 221 case CONTEXT_MAINMENU:
222 return button_context_menu;
223 case CONTEXT_LIST:
216 default: 224 default:
217 return button_context_standard; 225 return button_context_standard;
218 } 226 }
diff --git a/apps/keymaps/keymap-player.c b/apps/keymaps/keymap-player.c
index 82508b5c48..80cdedfc3c 100644
--- a/apps/keymaps/keymap-player.c
+++ b/apps/keymaps/keymap-player.c
@@ -78,6 +78,12 @@ static const struct button_mapping button_context_tree[] = {
78 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 78 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
79}; /* button_context_listtree */ 79}; /* button_context_listtree */
80 80
81static const struct button_mapping button_context_menu[] = {
82 { ACTION_MENU_WPS, BUTTON_ON, BUTTON_NONE },
83
84 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
85}; /* button_context_menu */
86
81static const struct button_mapping button_context_yesno[] = { 87static const struct button_mapping button_context_yesno[] = {
82 { ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE }, 88 { ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
83 89
@@ -153,9 +159,10 @@ const struct button_mapping* get_context_mapping( int context )
153 return button_context_tree; 159 return button_context_tree;
154 case CONTEXT_BOOKMARKSCREEN: 160 case CONTEXT_BOOKMARKSCREEN:
155 return button_context_bmark; 161 return button_context_bmark;
162 case CONTEXT_MAINMENU:
163 return button_context_menu;
156 case CONTEXT_STD: 164 case CONTEXT_STD:
157 case CONTEXT_LIST: 165 case CONTEXT_LIST:
158 case CONTEXT_MAINMENU:
159 default: 166 default:
160 return button_context_standard; 167 return button_context_standard;
161 } 168 }
diff --git a/apps/keymaps/keymap-recorder.c b/apps/keymaps/keymap-recorder.c
index 0296a87ce9..fc781afa46 100644
--- a/apps/keymaps/keymap-recorder.c
+++ b/apps/keymaps/keymap-recorder.c
@@ -112,6 +112,13 @@ static const struct button_mapping button_context_tree[] = {
112 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 112 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
113}; /* button_context_listtree */ 113}; /* button_context_listtree */
114 114
115static const struct button_mapping button_context_menu[] = {
116 { ACTION_MENU_WPS, BUTTON_ON|BUTTON_REL, BUTTON_ON },
117 { ACTION_MENU_STOP, BUTTON_OFF, BUTTON_NONE },
118 { ACTION_NONE, BUTTON_ON, BUTTON_NONE },
119 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
120}; /* button_context_listtree */
121
115static const struct button_mapping button_context_tree_scroll_lr[] = { 122static const struct button_mapping button_context_tree_scroll_lr[] = {
116 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE }, 123 { ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
117 { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, 124 { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
@@ -299,9 +306,10 @@ const struct button_mapping* get_context_mapping( int context )
299 case CONTEXT_FM: 306 case CONTEXT_FM:
300 return button_context_radio; 307 return button_context_radio;
301 308
309 case CONTEXT_MAINMENU:
310 return button_context_menu;
302 case CONTEXT_STD: 311 case CONTEXT_STD:
303 case CONTEXT_LIST: 312 case CONTEXT_LIST:
304 case CONTEXT_MAINMENU:
305 default: 313 default:
306 return button_context_standard; 314 return button_context_standard;
307 } 315 }
diff --git a/apps/keymaps/keymap-x5.c b/apps/keymaps/keymap-x5.c
index 82cfd27c5d..06e6b252d0 100644
--- a/apps/keymaps/keymap-x5.c
+++ b/apps/keymaps/keymap-x5.c
@@ -117,7 +117,7 @@ static const struct button_mapping button_context_keyboard[] = {
117/* Main Menu Context Menu **/ 117/* Main Menu Context Menu **/
118static const struct button_mapping button_context_mainmenu[] = { 118static const struct button_mapping button_context_mainmenu[] = {
119 { ACTION_NONE, BUTTON_POWER, BUTTON_NONE }, 119 { ACTION_NONE, BUTTON_POWER, BUTTON_NONE },
120 120 { ACTION_MENU_WPS, BUTTON_PLAY, BUTTON_NONE },
121 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 121 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
122}; /* button_context_mainmenu */ 122}; /* button_context_mainmenu */
123 123
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 08f06ba56b..40d0737ce1 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -314,13 +314,13 @@
314 desc: in the main menu 314 desc: in the main menu
315 user: 315 user:
316 <source> 316 <source>
317 *: "Playlist Options" 317 *: "Playlist"
318 </source> 318 </source>
319 <dest> 319 <dest>
320 *: "Playlist Options" 320 *: "Playlist"
321 </dest> 321 </dest>
322 <voice> 322 <voice>
323 *: "Playlist Options" 323 *: "Playlist"
324 </voice> 324 </voice>
325</phrase> 325</phrase>
326<phrase> 326<phrase>
@@ -328,13 +328,13 @@
328 desc: in the main menu 328 desc: in the main menu
329 user: 329 user:
330 <source> 330 <source>
331 *: "Browse Plugins" 331 *: "Plugins"
332 </source> 332 </source>
333 <dest> 333 <dest>
334 *: "Browse Plugins" 334 *: "Plugins"
335 </dest> 335 </dest>
336 <voice> 336 <voice>
337 *: "Browse Plugins" 337 *: "Plugins"
338 </voice> 338 </voice>
339</phrase> 339</phrase>
340<phrase> 340<phrase>
@@ -342,13 +342,13 @@
342 desc: in the main menu 342 desc: in the main menu
343 user: 343 user:
344 <source> 344 <source>
345 *: "Info" 345 *: "System"
346 </source> 346 </source>
347 <dest> 347 <dest>
348 *: "Info" 348 *: "System"
349 </dest> 349 </dest>
350 <voice> 350 <voice>
351 *: "Info" 351 *: "System"
352 </voice> 352 </voice>
353</phrase> 353</phrase>
354<phrase> 354<phrase>
@@ -1008,13 +1008,13 @@
1008 desc: in the recording sub menu 1008 desc: in the recording sub menu
1009 user: 1009 user:
1010 <source> 1010 <source>
1011 *: "Recording Screen" 1011 *: "Recording"
1012 </source> 1012 </source>
1013 <dest> 1013 <dest>
1014 *: "Recording Screen" 1014 *: "Recording"
1015 </dest> 1015 </dest>
1016 <voice> 1016 <voice>
1017 *: "Recording Screen" 1017 *: "Recording"
1018 </voice> 1018 </voice>
1019</phrase> 1019</phrase>
1020<phrase> 1020<phrase>
@@ -10563,3 +10563,115 @@
10563 *: "FM Radio Menu" 10563 *: "FM Radio Menu"
10564 </voice> 10564 </voice>
10565</phrase> 10565</phrase>
10566<phrase>
10567 id: LANG_DIR_BROWSER
10568 desc: in root menu
10569 user:
10570 <source>
10571 *: "Files"
10572 </source>
10573 <dest>
10574 *: "Files"
10575 </dest>
10576 <voice>
10577 *: "Files"
10578 </voice>
10579</phrase>
10580<phrase>
10581 id: LANG_SETTINGS_MENU
10582 desc: in root menu
10583 user:
10584 <source>
10585 *: "Settings"
10586 </source>
10587 <dest>
10588 *: "Settings"
10589 </dest>
10590 <voice>
10591 *: "Settings"
10592 </voice>
10593</phrase>
10594<phrase>
10595 id: LANG_NOW_PLAYING
10596 desc: in root menu
10597 user:
10598 <source>
10599 *: "Now Playing"
10600 </source>
10601 <dest>
10602 *: "Now Playing"
10603 </dest>
10604 <voice>
10605 *: "Now Playing"
10606 </voice>
10607</phrase>
10608<phrase>
10609 id: LANG_RESUME_PLAYBACK
10610 desc: in root menu
10611 user:
10612 <source>
10613 *: "Resume Playback"
10614 </source>
10615 <dest>
10616 *: "Resume Playback"
10617 </dest>
10618 <voice>
10619 *: "Resume Playback"
10620 </voice>
10621</phrase>
10622<phrase>
10623 id: LANG_START_SCREEN
10624 desc: in root menu setting
10625 user:
10626 <source>
10627 *: "Start Screen"
10628 </source>
10629 <dest>
10630 *: "Start Screen"
10631 </dest>
10632 <voice>
10633 *: "Start Screen"
10634 </voice>
10635</phrase>
10636<phrase>
10637 id: LANG_ROCKBOX_TITLE
10638 desc: in root menu
10639 user:
10640 <source>
10641 *: "Rockbox"
10642 </source>
10643 <dest>
10644 *: "Rockbox"
10645 </dest>
10646 <voice>
10647 *: "Rockbox"
10648 </voice>
10649</phrase>
10650<phrase>
10651 id: LANG_MAIN_MENU
10652 desc: in root menu setting
10653 user:
10654 <source>
10655 *: "Main Menu"
10656 </source>
10657 <dest>
10658 *: "Main Menu"
10659 </dest>
10660 <voice>
10661 *: "Main Menu"
10662 </voice>
10663</phrase>
10664<phrase>
10665 id: LANG_PREVIOUS_SCREEN
10666 desc: in root menu setting
10667 user:
10668 <source>
10669 *: "Previous Screen"
10670 </source>
10671 <dest>
10672 *: "Previous Screen"
10673 </dest>
10674 <voice>
10675 *: "Previous Screen"
10676 </voice>
10677</phrase>
diff --git a/apps/main_menu.c b/apps/main_menu.c
index e3cc88fdda..ec139466cb 100644
--- a/apps/main_menu.c
+++ b/apps/main_menu.c
@@ -128,9 +128,6 @@ bool main_menu(void)
128 if(inside_menu) return false; 128 if(inside_menu) return false;
129 inside_menu = true; 129 inside_menu = true;
130 130
131 items[i].desc = ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS);
132 items[i++].function = bookmark_mrb_load;
133
134 items[i].desc = ID2P(LANG_SOUND_SETTINGS); 131 items[i].desc = ID2P(LANG_SOUND_SETTINGS);
135 items[i++].function = sound_menu; 132 items[i++].function = sound_menu;
136 133
diff --git a/apps/main_menu.h b/apps/main_menu.h
index d1c36b3663..c70640fd77 100644
--- a/apps/main_menu.h
+++ b/apps/main_menu.h
@@ -21,7 +21,7 @@
21 21
22#include "menu.h" 22#include "menu.h"
23 23
24extern bool main_menu(void); 24extern int main_menu(void);
25extern bool rec_menu(void); 25extern bool rec_menu(void);
26 26
27#endif 27#endif
diff --git a/apps/menu.c b/apps/menu.c
index 0081d4964d..8656c903c7 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -23,6 +23,7 @@
23*/ 23*/
24#include <stdbool.h> 24#include <stdbool.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include "config.h"
26 27
27#include "hwcompat.h" 28#include "hwcompat.h"
28#include "lcd.h" 29#include "lcd.h"
@@ -44,6 +45,10 @@
44#include "action.h" 45#include "action.h"
45#include "menus/exported_menus.h" 46#include "menus/exported_menus.h"
46#include "string.h" 47#include "string.h"
48#include "root_menu.h"
49#include "bookmark.h"
50#include "gwps-common.h" /* for fade() */
51#include "audio.h"
47 52
48#ifdef HAVE_LCD_BITMAP 53#ifdef HAVE_LCD_BITMAP
49#include "icons.h" 54#include "icons.h"
@@ -303,7 +308,14 @@ static int get_menu_selection(int selected_item, const struct menu_item_ex *menu
303 return current_subitems[selected_item]; 308 return current_subitems[selected_item];
304 return selected_item; 309 return selected_item;
305} 310}
306 311static int find_menu_selection(int selected)
312{
313 int i;
314 for (i=0; i< current_subitems_count; i++)
315 if (current_subitems[i] == selected)
316 return i;
317 return 0;
318}
307static char * get_menu_item_name(int selected_item,void * data, char *buffer) 319static char * get_menu_item_name(int selected_item,void * data, char *buffer)
308{ 320{
309 const struct menu_item_ex *menu = (const struct menu_item_ex *)data; 321 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)
363 break; 375 break;
364 case MT_FUNCTION_CALL: 376 case MT_FUNCTION_CALL:
365 case MT_FUNCTION_WITH_PARAM: 377 case MT_FUNCTION_WITH_PARAM:
378 case MT_RETURN_VALUE:
366 if (menu_icon == NOICON) 379 if (menu_icon == NOICON)
367 *icon = bitmap_icons_6x8[Icon_Menu_functioncall]; 380 *icon = bitmap_icons_6x8[Icon_Menu_functioncall];
368 else 381 else
@@ -418,7 +431,7 @@ static void init_menu_lists(const struct menu_item_ex *menu,
418 gui_synclist_set_icon_callback(lists, NULL); 431 gui_synclist_set_icon_callback(lists, NULL);
419 gui_synclist_set_nb_items(lists,current_subitems_count); 432 gui_synclist_set_nb_items(lists,current_subitems_count);
420 gui_synclist_limit_scroll(lists,true); 433 gui_synclist_limit_scroll(lists,true);
421 gui_synclist_select_item(lists, selected); 434 gui_synclist_select_item(lists, find_menu_selection(selected));
422 435
423 get_menu_callback(menu,&menu_callback); 436 get_menu_callback(menu,&menu_callback);
424 if (callback && menu_callback) 437 if (callback && menu_callback)
@@ -434,14 +447,14 @@ static void talk_menu_item(const struct menu_item_ex *menu,
434 int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu); 447 int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
435 if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) 448 if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
436 { 449 {
437 if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING) 450 if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
438 talk_setting(menu->submenus[sel]->variable); 451 talk_setting(menu->submenus[sel]->variable);
439 else 452 else
440 { 453 {
441 id = P2ID(menu->submenus[sel]->callback_and_desc->desc); 454 id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
442 if (id != -1) 455 if (id != -1)
443 talk_id(id,false); 456 talk_id(id,false);
444 } 457 }
445 } 458 }
446 } 459 }
447} 460}
@@ -564,10 +577,10 @@ bool do_setting_from_menu(const struct menu_item_ex *temp)
564 return ret_val; 577 return ret_val;
565} 578}
566 579
567int do_menu(const struct menu_item_ex *start_menu) 580int do_menu(const struct menu_item_ex *start_menu, int *start_selected)
568{ 581{
582 int selected = start_selected? *start_selected : 0;
569 int action; 583 int action;
570 int selected = 0;
571 struct gui_synclist lists; 584 struct gui_synclist lists;
572 const struct menu_item_ex *temp, *menu; 585 const struct menu_item_ex *temp, *menu;
573 int ret = 0; 586 int ret = 0;
@@ -630,10 +643,24 @@ int do_menu(const struct menu_item_ex *start_menu)
630 } 643 }
631 else if (action == ACTION_MENU_WPS) 644 else if (action == ACTION_MENU_WPS)
632 { 645 {
633 ret = MENU_RETURN_TO_WPS; 646 ret = GO_TO_PREVIOUS_MUSIC;
634 } 647 }
635 else if ((action == ACTION_STD_CANCEL) || 648 else if (action == ACTION_MENU_STOP)
636 (action == ACTION_STD_MENU)) 649 {
650 if (audio_status() && !global_settings.party_mode)
651 {
652 if (global_settings.fade_on_stop)
653 fade(0);
654 bookmark_autobookmark();
655 audio_stop();
656 }
657 }
658 else if (action == ACTION_STD_MENU)
659 {
660 if (menu != &root_menu_)
661 ret = GO_TO_ROOT;
662 }
663 else if (action == ACTION_STD_CANCEL)
637 { 664 {
638 in_stringlist = false; 665 in_stringlist = false;
639 if (menu_callback) 666 if (menu_callback)
@@ -649,8 +676,11 @@ int do_menu(const struct menu_item_ex *start_menu)
649 /* new menu, so reload the callback */ 676 /* new menu, so reload the callback */
650 get_menu_callback(menu, &menu_callback); 677 get_menu_callback(menu, &menu_callback);
651 } 678 }
652 else 679 else if (menu != &root_menu_)
680 {
681 ret = GO_TO_PREVIOUS;
653 break; 682 break;
683 }
654 } 684 }
655 else if (action == ACTION_STD_OK) 685 else if (action == ACTION_STD_OK)
656 { 686 {
@@ -678,8 +708,7 @@ int do_menu(const struct menu_item_ex *start_menu)
678 if (stack_top < MAX_MENUS) 708 if (stack_top < MAX_MENUS)
679 { 709 {
680 menu_stack[stack_top] = menu; 710 menu_stack[stack_top] = menu;
681 menu_stack_selected_item[stack_top] 711 menu_stack_selected_item[stack_top] = selected;
682 = gui_synclist_get_sel_pos(&lists);
683 stack_top++; 712 stack_top++;
684 init_menu_lists(temp, &lists, 0, true); 713 init_menu_lists(temp, &lists, 0, true);
685 menu = temp; 714 menu = temp;
@@ -717,6 +746,10 @@ int do_menu(const struct menu_item_ex *start_menu)
717 in_stringlist = true; 746 in_stringlist = true;
718 } 747 }
719 break; 748 break;
749 case MT_RETURN_VALUE:
750 if (start_selected)
751 *start_selected = selected;
752 return temp->value;
720 } 753 }
721 if (type != MT_MENU && menu_callback) 754 if (type != MT_MENU && menu_callback)
722 menu_callback(ACTION_EXIT_MENUITEM,temp); 755 menu_callback(ACTION_EXIT_MENUITEM,temp);
@@ -733,10 +766,12 @@ int do_menu(const struct menu_item_ex *start_menu)
733 gui_synclist_draw(&lists); 766 gui_synclist_draw(&lists);
734 } 767 }
735 action_signalscreenchange(); 768 action_signalscreenchange();
769 if (start_selected)
770 *start_selected = selected;
736 return ret; 771 return ret;
737} 772}
738 773
739int main_menu(void) 774int main_menu(void)
740{ 775{
741 return do_menu(NULL); 776 return do_menu(NULL, 0);
742} 777}
diff --git a/apps/menu.h b/apps/menu.h
index 655c9112c4..4cb7446ae1 100644
--- a/apps/menu.h
+++ b/apps/menu.h
@@ -63,6 +63,7 @@ enum menu_item_type {
63 MT_FUNCTION_CALL, /* used when the standard code wont work */ 63 MT_FUNCTION_CALL, /* used when the standard code wont work */
64 MT_FUNCTION_WITH_PARAM, 64 MT_FUNCTION_WITH_PARAM,
65 MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/ 65 MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
66 MT_RETURN_VALUE, /* returns a value associated with an item */
66}; 67};
67 68
68typedef int (*menu_function)(void); 69typedef int (*menu_function)(void);
@@ -89,6 +90,7 @@ struct menu_item_ex {
89 const struct menu_func_with_param 90 const struct menu_func_with_param
90 *func_with_param; /* MT_FUNCTION_WITH_PARAM */ 91 *func_with_param; /* MT_FUNCTION_WITH_PARAM */
91 const char **strings; /* used with MT_RETURN_ID */ 92 const char **strings; /* used with MT_RETURN_ID */
93 int value; /* MT_RETURN_VALUE */
92 }; 94 };
93 union { 95 union {
94 /* For settings */ 96 /* For settings */
@@ -117,7 +119,7 @@ struct menu_item_ex {
117 119
118typedef int (*menu_callback_type)(int action, 120typedef int (*menu_callback_type)(int action,
119 const struct menu_item_ex *this_item); 121 const struct menu_item_ex *this_item);
120int do_menu(const struct menu_item_ex *menu); 122int do_menu(const struct menu_item_ex *menu, int *start_selected);
121bool do_setting_from_menu(const struct menu_item_ex *temp); 123bool do_setting_from_menu(const struct menu_item_ex *temp);
122 124
123#define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT) 125#define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT)
@@ -149,22 +151,37 @@ bool do_setting_from_menu(const struct menu_item_ex *temp);
149 151
150#ifdef HAVE_LCD_BITMAP /* Kill the player port already.... PLEASE!! */ 152#ifdef HAVE_LCD_BITMAP /* Kill the player port already.... PLEASE!! */
151 153
152/* This one should be static'ed also, 154/* returns a value associated with the item */
153 but cannot be done untill settings menu is done */ 155#define MENUITEM_RETURNVALUE(name, str, val, cb, icon) \
156 static const struct menu_callback_with_desc name##_ = {cb,str,icon}; \
157 static const struct menu_item_ex name = \
158 { MT_RETURN_VALUE|MENU_HAS_DESC, { .value = val}, \
159 {.callback_and_desc = & name##_}};
160
161/* same as above, except the item name is dynamic */
162#define MENUITEM_RETURNVALUE_DYNTEXT(name, val, cb, text_callback, text_cb_data, icon) \
163 static const struct menu_get_name_and_icon name##_ \
164 = {cb,text_callback,text_cb_data,icon}; \
165 static const struct menu_item_ex name = \
166 { MT_RETURN_VALUE|MENU_DYNAMIC_DESC, { .value = val}, \
167 {.menu_get_name_and_icon = & name##_}};
168
154/* Use this to put a function call into the menu. 169/* Use this to put a function call into the menu.
155 When the user selects this item the function will be run, 170 When the user selects this item the function will be run,
156 when it exits the user will be back in the menu. return value is ignored */ 171 when it exits the user will be back in the menu. return value is ignored */
157#define MENUITEM_FUNCTION(name, str, func, callback, icon) \ 172#define MENUITEM_FUNCTION(name, str, func, callback, icon) \
158 static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \ 173 static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \
159 const struct menu_item_ex name = \ 174 static const struct menu_item_ex name = \
160 { MT_FUNCTION_CALL|MENU_HAS_DESC, { .function = func}, \ 175 { MT_FUNCTION_CALL|MENU_HAS_DESC, { .function = func}, \
161 {.callback_and_desc = & name##_}}; 176 {.callback_and_desc = & name##_}};
162 177
178/* This one should be static'ed also,
179 but cannot be done untill recording menu is done */
163/* Same as above, except the function will be called with a (void*)param. */ 180/* Same as above, except the function will be called with a (void*)param. */
164#define MENUITEM_FUNCTION_WPARAM(name, str, func, param, callback, icon) \ 181#define MENUITEM_FUNCTION_WPARAM(name, str, func, param, callback, icon) \
165 static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \ 182 static const struct menu_callback_with_desc name##_ = {callback,str,icon}; \
166 static const struct menu_func_with_param name##__ = {func, param}; \ 183 static const struct menu_func_with_param name##__ = {func, param}; \
167 static const struct menu_item_ex name = \ 184 const struct menu_item_ex name = \
168 { MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC, \ 185 { MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC, \
169 { .func_with_param = &name##__}, \ 186 { .func_with_param = &name##__}, \
170 {.callback_and_desc = & name##_}}; 187 {.callback_and_desc = & name##_}};
@@ -189,8 +206,20 @@ bool do_setting_from_menu(const struct menu_item_ex *temp);
189 {MT_MENU|MENU_HAS_DESC| \ 206 {MT_MENU|MENU_HAS_DESC| \
190 MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \ 207 MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \
191 { (void*)name##_},{.callback_and_desc = & name##__}}; 208 { (void*)name##_},{.callback_and_desc = & name##__}};
209
192 210
193#else /* HAVE_LCD_BITMAP */ 211#else /* HAVE_LCD_BITMAP */
212#define MENUITEM_RETURNVALUE(name, str, val, cb, icon) \
213 static const struct menu_callback_with_desc name##_ = {cb,str}; \
214 static const struct menu_item_ex name = \
215 { MT_RETURN_VALUE|MENU_HAS_DESC, { .value = val}, \
216 {.callback_and_desc = & name##_}};
217#define MENUITEM_RETURNVALUE_DYNTEXT(name, val, cb, text_callback, text_cb_data, icon) \
218 static const struct menu_get_name_and_icon name##_ \
219 = {cb,text_callback,text_cb_data}; \
220 static const struct menu_item_ex name = \
221 { MT_RETURN_VALUE|MENU_DYNAMIC_DESC, { .value = val}, \
222 {.menu_get_name_and_icon = & name##_}};
194#define MENUITEM_FUNCTION(name, str, func, callback, icon) \ 223#define MENUITEM_FUNCTION(name, str, func, callback, icon) \
195 static const struct menu_callback_with_desc name##_ = {callback,str}; \ 224 static const struct menu_callback_with_desc name##_ = {callback,str}; \
196 const struct menu_item_ex name = \ 225 const struct menu_item_ex name = \
diff --git a/apps/menus/eq_menu.c b/apps/menus/eq_menu.c
index c66e5a20c0..25ab170169 100644
--- a/apps/menus/eq_menu.c
+++ b/apps/menus/eq_menu.c
@@ -187,7 +187,7 @@ int do_center_band_menu(void* param)
187 menu.flags = MT_MENU|(3<<MENU_COUNT_SHIFT)|MENU_HAS_DESC; 187 menu.flags = MT_MENU|(3<<MENU_COUNT_SHIFT)|MENU_HAS_DESC;
188 menu.submenus = band_items[band-1]; 188 menu.submenus = band_items[band-1];
189 menu.callback_and_desc = &cb_and_desc; 189 menu.callback_and_desc = &cb_and_desc;
190 do_menu(&menu); 190 do_menu(&menu, NULL);
191 return 0; 191 return 0;
192} 192}
193MAKE_MENU(band_0_menu, ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), NULL, 193MAKE_MENU(band_0_menu, ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), NULL,
diff --git a/apps/menus/exported_menus.h b/apps/menus/exported_menus.h
index f6b6f5a708..a4f8512a73 100644
--- a/apps/menus/exported_menus.h
+++ b/apps/menus/exported_menus.h
@@ -28,12 +28,14 @@ extern const struct menu_item_ex
28 display_menu, /* display_menu.c */ 28 display_menu, /* display_menu.c */
29 playback_menu_item, /* playback_menu.c */ 29 playback_menu_item, /* playback_menu.c */
30#ifdef HAVE_RECORDING 30#ifdef HAVE_RECORDING
31 recording_settings_menu, /* recording_menu.c */ 31 recording_settings, /* recording_menu.c */
32#endif 32#endif
33 sound_settings, /* sound_menu.c */ 33 sound_settings, /* sound_menu.c */
34 settings_menu_item, /* settings_menu.c */ 34 settings_menu_item, /* settings_menu.c */
35 playlist_menu_item, /* playlist_menu.c */ 35 playlist_settings, /* playlist_menu.c */
36 equalizer_menu; /* eq_menu.c */ 36 playlist_options, /* playlist_menu.c */
37 equalizer_menu, /* eq_menu.c */
38 info_menu; /* info_menu.c */
37 39
38#ifdef HAVE_WM8758 40#ifdef HAVE_WM8758
39extern const struct menu_item_ex hw_eq_menu; /* eq_menu.c */ 41extern const struct menu_item_ex hw_eq_menu; /* eq_menu.c */
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index b367fded35..d986436311 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -30,9 +30,6 @@
30#include "settings_menu.h" 30#include "settings_menu.h"
31#include "exported_menus.h" 31#include "exported_menus.h"
32#include "tree.h" 32#include "tree.h"
33#if CONFIG_TUNER
34#include "radio.h"
35#endif
36#ifdef HAVE_RECORDING 33#ifdef HAVE_RECORDING
37#include "recording.h" 34#include "recording.h"
38#endif 35#endif
@@ -49,9 +46,6 @@
49#include "logfdisp.h" 46#include "logfdisp.h"
50#endif 47#endif
51 48
52/* lazy coders can use this function if the needed callback
53 is just to say if the item is shown or not */
54int dynamicitem_callback(int action,const struct menu_item_ex *this_item);
55 49
56 50
57struct browse_folder_info { 51struct browse_folder_info {
@@ -59,12 +53,11 @@ struct browse_folder_info {
59 int show_options; 53 int show_options;
60}; 54};
61static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG}; 55static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
62static struct browse_folder_info rocks = {PLUGIN_DIR, SHOW_PLUGINS};
63static struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG}; 56static struct browse_folder_info config = {ROCKBOX_DIR, SHOW_CFG};
64static int browse_folder(void *param) 57static int browse_folder(void *param)
65{ 58{
66 const struct browse_folder_info *info = 59 const struct browse_folder_info *info =
67 (const struct browse_folder_info*)param; 60 (const struct browse_folder_info*)param;
68 return rockbox_browse(info->dir, info->show_options); 61 return rockbox_browse(info->dir, info->show_options);
69} 62}
70 63
@@ -384,26 +377,6 @@ MAKE_MENU(info_menu, ID2P(LANG_INFO), 0, bitmap_icons_6x8[Icon_Questionmark],
384 377
385MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME), 378MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME),
386 browse_folder, (void*)&theme, NULL, bitmap_icons_6x8[Icon_Folder]); 379 browse_folder, (void*)&theme, NULL, bitmap_icons_6x8[Icon_Folder]);
387MENUITEM_FUNCTION_WPARAM(browse_plugins, ID2P(LANG_PLUGINS),
388 browse_folder, (void*)&rocks, NULL, bitmap_icons_6x8[Icon_Plugin]);
389
390#if CONFIG_TUNER
391MENUITEM_FUNCTION(load_radio_screen, ID2P(LANG_FM_RADIO),
392 (menu_function)radio_screen, dynamicitem_callback,
393 bitmap_icons_6x8[Icon_Radio_screen]);
394#endif
395
396MENUITEM_FUNCTION(mrb_bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
397 (menu_function)bookmark_mrb_load, NULL, bitmap_icons_6x8[Icon_Bookmark]);
398
399#ifdef HAVE_LCD_CHARCELLS
400static int do_shutdown(void)
401{
402 sys_poweroff();
403 return 0;
404}
405MENUITEM_FUNCTION(do_shutdown_item, ID2P(LANG_SHUTDOWN), do_shutdown, NULL, NOICON);
406#endif
407 380
408#ifdef HAVE_LCD_CHARCELLS 381#ifdef HAVE_LCD_CHARCELLS
409int mainmenu_callback(int action,const struct menu_item_ex *this_item) 382int 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)
423#else 396#else
424#define mainmenu_callback NULL 397#define mainmenu_callback NULL
425#endif 398#endif
426/* NOTE: This title will be translatable once we decide what to call this menu 399MAKE_MENU(main_menu_, ID2P(LANG_SETTINGS_MENU), mainmenu_callback,
427 when the root menu comes in... hopefully in the next few days */
428MAKE_MENU(main_menu_, "Rockbox Main Menu", mainmenu_callback,
429 bitmap_icons_6x8[Icon_Submenu_Entered], 400 bitmap_icons_6x8[Icon_Submenu_Entered],
430 &mrb_bookmarks, &sound_settings, 401 &sound_settings,
431 &settings_menu_item, &manage_settings, &browse_themes, 402 &settings_menu_item, &manage_settings, &browse_themes,
432#if CONFIG_TUNER
433 &load_radio_screen,
434#endif
435#ifdef HAVE_RECORDING 403#ifdef HAVE_RECORDING
436 &recording_settings_menu, 404 &recording_settings,
437#endif
438 &playlist_menu_item, &browse_plugins, &info_menu
439#ifdef HAVE_LCD_CHARCELLS
440 ,&do_shutdown_item
441#endif 405#endif
442 ); 406 );
443/* MAIN MENU */ 407/* MAIN MENU */
444/***********************************/ 408/***********************************/
445 409
446/* lazy coders can use this function if the needed
447 callback is just to say if the item is shown or not */
448int dynamicitem_callback(int action,const struct menu_item_ex *this_item)
449{
450 if (action != ACTION_REQUEST_MENUITEM)
451 return action;
452
453#if CONFIG_TUNER
454 if (this_item == &load_radio_screen)
455 {
456 if (radio_hardware_present() == 0)
457 return ACTION_EXIT_MENUITEM;
458 }
459#else
460 (void)this_item;
461#endif
462
463 return action;
464}
diff --git a/apps/menus/playback_menu.c b/apps/menus/playback_menu.c
index 6345b67ace..ae735609a8 100644
--- a/apps/menus/playback_menu.c
+++ b/apps/menus/playback_menu.c
@@ -57,7 +57,6 @@ int playback_callback(int action,const struct menu_item_ex *this_item);
57MENUITEM_SETTING(shuffle_item, &global_settings.playlist_shuffle, playback_callback); 57MENUITEM_SETTING(shuffle_item, &global_settings.playlist_shuffle, playback_callback);
58MENUITEM_SETTING(repeat_mode, &global_settings.repeat_mode, playback_callback); 58MENUITEM_SETTING(repeat_mode, &global_settings.repeat_mode, playback_callback);
59MENUITEM_SETTING(play_selected, &global_settings.play_selected, NULL); 59MENUITEM_SETTING(play_selected, &global_settings.play_selected, NULL);
60MENUITEM_SETTING(resume, &global_settings.resume, NULL);
61 60
62MENUITEM_SETTING(ff_rewind_accel, &global_settings.ff_rewind_accel, NULL); 61MENUITEM_SETTING(ff_rewind_accel, &global_settings.ff_rewind_accel, NULL);
63MENUITEM_SETTING(ff_rewind_min_step, &global_settings.ff_rewind_min_step, NULL); 62MENUITEM_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)
108 (void)this_item; 107 (void)this_item;
109 switch (action) 108 switch (action)
110 { 109 {
111 case ACTION_EXIT_MENUITEM: /* on exit */ 110 case ACTION_EXIT_MENUITEM: /* on exit */
112 dsp_set_replaygain(); 111 dsp_set_replaygain();
113 break; 112 break;
114 } 113 }
@@ -172,7 +171,7 @@ MAKE_MENU(unplug_menu, ID2P(LANG_UNPLUG), 0, NOICON,
172 171
173MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0, 172MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
174 bitmap_icons_6x8[Icon_Playback_menu], 173 bitmap_icons_6x8[Icon_Playback_menu],
175 &shuffle_item, &repeat_mode, &play_selected, &resume, 174 &shuffle_item, &repeat_mode, &play_selected,
176 &ff_rewind_settings_menu, 175 &ff_rewind_settings_menu,
177 &buffer_margin, &fade_on_stop, &party_mode, 176 &buffer_margin, &fade_on_stop, &party_mode,
178 177
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index f179265279..d0d491f74e 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -73,12 +73,14 @@ MENUITEM_FUNCTION(catalog, ID2P(LANG_CATALOG),
73MENUITEM_SETTING(recursive_dir_insert, &global_settings.recursive_dir_insert, NULL); 73MENUITEM_SETTING(recursive_dir_insert, &global_settings.recursive_dir_insert, NULL);
74MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL); 74MENUITEM_SETTING(warn_on_erase, &global_settings.warnon_erase_dynplaylist, NULL);
75 75
76MAKE_MENU(playlist_menu_item, ID2P(LANG_PLAYLIST_MENU), NULL, 76MAKE_MENU(playlist_settings, ID2P(LANG_PLAYLIST_MENU), NULL,
77 bitmap_icons_6x8[Icon_Playlist], 77 bitmap_icons_6x8[Icon_Playlist],
78 &create_playlist_item, &view_playlist, &save_playlist, &catalog,
79 &recursive_dir_insert, &warn_on_erase); 78 &recursive_dir_insert, &warn_on_erase);
79MAKE_MENU(playlist_options, ID2P(LANG_PLAYLIST_MENU), NULL,
80 bitmap_icons_6x8[Icon_Playlist],
81 &create_playlist_item, &view_playlist, &save_playlist, &catalog);
80 82
81bool playlist_menu(void) 83bool playlist_menu(void)
82{ 84{
83 return do_menu(&playlist_menu_item); 85 return do_menu(&playlist_options, NULL);
84} 86}
diff --git a/apps/menus/recording_menu.c b/apps/menus/recording_menu.c
index 0b4ba52715..028b57bb99 100644
--- a/apps/menus/recording_menu.c
+++ b/apps/menus/recording_menu.c
@@ -29,14 +29,8 @@
29#include "recording.h" 29#include "recording.h"
30 30
31#ifdef HAVE_RECORDING 31#ifdef HAVE_RECORDING
32MENUITEM_FUNCTION(rec_menu_recording_screen_item, ID2P(LANG_RECORDING_MENU),
33 (menu_function)recording_screen, NULL, NOICON);
34/* TEMP */ 32/* TEMP */
35bool recording_menu(bool no_source); /* from apps/sound_menu.h */ 33bool recording_menu(bool no_source); /* from apps/sound_menu.h */
36MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_SETTINGS), 34MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_SETTINGS),
37 (int (*)(void*))recording_menu,0, NULL, NOICON); 35 (int (*)(void*))recording_menu,0, NULL, NOICON);
38
39MAKE_MENU(recording_settings_menu,ID2P(LANG_RECORDING),
40 0, bitmap_icons_6x8[Icon_Recording],
41 &rec_menu_recording_screen_item, &recording_settings);
42#endif 36#endif
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c
index 92c169e43a..35b7e2bf2f 100644
--- a/apps/menus/settings_menu.c
+++ b/apps/menus/settings_menu.c
@@ -281,9 +281,11 @@ MENUITEM_SETTING(line_in, &global_settings.line_in, linein_callback);
281#if CONFIG_CHARGING 281#if CONFIG_CHARGING
282MENUITEM_SETTING(car_adapter_mode, &global_settings.car_adapter_mode, NULL); 282MENUITEM_SETTING(car_adapter_mode, &global_settings.car_adapter_mode, NULL);
283#endif 283#endif
284MENUITEM_SETTING(start_screen, &global_settings.start_in_screen, NULL);
284 285
285MAKE_MENU(system_menu, ID2P(LANG_SYSTEM), 286MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
286 0, bitmap_icons_6x8[Icon_System_menu], 287 0, bitmap_icons_6x8[Icon_System_menu],
288 &start_screen,
287#ifndef SIMULATOR 289#ifndef SIMULATOR
288 &battery_menu, 290 &battery_menu,
289#endif 291#endif
@@ -385,7 +387,8 @@ MENUITEM_FUNCTION(browse_langs, ID2P(LANG_LANGUAGE), language_browse,
385 387
386MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0, 388MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0,
387 bitmap_icons_6x8[Icon_General_settings_menu], 389 bitmap_icons_6x8[Icon_General_settings_menu],
388 &playback_menu_item, &file_menu, &display_menu, &system_menu, 390 &playback_menu_item, &playlist_settings, &file_menu,
391 &display_menu, &system_menu,
389 &bookmark_settings_menu, &browse_langs, &voice_settings_menu ); 392 &bookmark_settings_menu, &browse_langs, &voice_settings_menu );
390/* SETTINGS MENU */ 393/* SETTINGS MENU */
391/***********************************/ 394/***********************************/
diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c
index 287b3ec904..1fa8ec6d02 100644
--- a/apps/menus/sound_menu.c
+++ b/apps/menus/sound_menu.c
@@ -113,5 +113,5 @@ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, bitmap_icons_6x8[Icon
113 113
114bool sound_menu(void) 114bool sound_menu(void)
115{ 115{
116 return do_menu(&sound_settings); 116 return do_menu(&sound_settings, 0);
117} 117}
diff --git a/apps/onplay.c b/apps/onplay.c
index 8f19c18d42..a0da3ac2d9 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -1043,7 +1043,7 @@ int onplay(char* file, int attr, int from)
1043 menu_exit(m); 1043 menu_exit(m);
1044 1044
1045 if (exit_to_main) 1045 if (exit_to_main)
1046 result = main_menu(); 1046 onplay_result = ONPLAY_MAINMENU;
1047 1047
1048#ifdef HAVE_LCD_BITMAP 1048#ifdef HAVE_LCD_BITMAP
1049 if (global_settings.statusbar) 1049 if (global_settings.statusbar)
diff --git a/apps/onplay.h b/apps/onplay.h
index 08737becca..f842764eb5 100644
--- a/apps/onplay.h
+++ b/apps/onplay.h
@@ -22,7 +22,8 @@
22int onplay(char* file, int attr, int from_screen); 22int onplay(char* file, int attr, int from_screen);
23 23
24enum { 24enum {
25 ONPLAY_OK, 25 ONPLAY_MAINMENU = -1,
26 ONPLAY_OK = 0,
26 ONPLAY_RELOAD_DIR, 27 ONPLAY_RELOAD_DIR,
27 ONPLAY_START_PLAY 28 ONPLAY_START_PLAY
28}; 29};
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index d3a4f97763..ccb42d5919 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -79,6 +79,7 @@ const unsigned char bitmap_icons_6x8[][6] =
79#endif 79#endif
80 { 0x1f, 0x11, 0x7d, 0x46, 0x44, 0x78 }, /* File View Menu */ 80 { 0x1f, 0x11, 0x7d, 0x46, 0x44, 0x78 }, /* File View Menu */
81 { 0x06, 0x7f, 0x06, 0x18, 0x7f, 0x18 }, /* EQ menu */ 81 { 0x06, 0x7f, 0x06, 0x18, 0x7f, 0x18 }, /* EQ menu */
82 { 0x20, 0x70, 0x70, 0x3f, 0x0a, 0x0a }, /* "rockbox" musical note */
82}; 83};
83 84
84const unsigned char bitmap_icons_7x8[][7] = 85const unsigned char bitmap_icons_7x8[][7] =
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 605341593a..3503e73f6d 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -83,6 +83,7 @@ enum icons_6x8 {
83#endif 83#endif
84 Icon_file_view_menu, 84 Icon_file_view_menu,
85 Icon_EQ, 85 Icon_EQ,
86 Icon_Rockbox,
86 Icon6x8Last, 87 Icon6x8Last,
87}; 88};
88 89
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index d264589e38..f15a10f329 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -62,6 +62,7 @@
62#include "action.h" 62#include "action.h"
63#include "list.h" 63#include "list.h"
64#include "menus/exported_menus.h" 64#include "menus/exported_menus.h"
65#include "root_menu.h"
65 66
66#if CONFIG_TUNER 67#if CONFIG_TUNER
67 68
@@ -365,11 +366,12 @@ static void next_preset(int direction)
365} 366}
366 367
367 368
368bool radio_screen(void) 369int radio_screen(void)
369{ 370{
370 char buf[MAX_PATH]; 371 char buf[MAX_PATH];
371 bool done = false; 372 bool done = false;
372 int button, lastbutton = BUTTON_NONE; 373 int button, lastbutton = BUTTON_NONE;
374 int ret_val = GO_TO_ROOT;
373#ifdef FM_RECORD_DBLPRE 375#ifdef FM_RECORD_DBLPRE
374 unsigned long rec_lastclick = 0; 376 unsigned long rec_lastclick = 0;
375#endif 377#endif
@@ -582,7 +584,7 @@ bool radio_screen(void)
582#endif 584#endif
583 keep_playing = true; 585 keep_playing = true;
584 done = true; 586 done = true;
585 587 ret_val = GO_TO_ROOT;
586 if(presets_changed) 588 if(presets_changed)
587 { 589 {
588 if(yesno_pop(str(LANG_FM_SAVE_CHANGES))) 590 if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
@@ -596,7 +598,7 @@ bool radio_screen(void)
596 598
597 /* Clear the preset list on exit. */ 599 /* Clear the preset list on exit. */
598 clear_preset_list(); 600 clear_preset_list();
599 601
600 break; 602 break;
601 603
602 case ACTION_STD_PREV: 604 case ACTION_STD_PREV:
@@ -1277,7 +1279,7 @@ static int handle_radio_presets(void)
1277 case ACTION_F3: 1279 case ACTION_F3:
1278 case ACTION_STD_CONTEXT: 1280 case ACTION_STD_CONTEXT:
1279 selected_preset = gui_synclist_get_sel_pos(&lists); 1281 selected_preset = gui_synclist_get_sel_pos(&lists);
1280 do_menu(&handle_radio_preset_menu); 1282 do_menu(&handle_radio_preset_menu, NULL);
1281 break; 1283 break;
1282 default: 1284 default:
1283 if(default_event_handler(action) == SYS_USB_CONNECTED) 1285 if(default_event_handler(action) == SYS_USB_CONNECTED)
@@ -1501,7 +1503,7 @@ MAKE_MENU(radio_menu_items, ID2P(LANG_FM_MENU), NULL,
1501/* main menu of the radio screen */ 1503/* main menu of the radio screen */
1502static bool radio_menu(void) 1504static bool radio_menu(void)
1503{ 1505{
1504 return (bool)do_menu(&radio_menu_items); 1506 return (bool)do_menu(&radio_menu_items, NULL);
1505} 1507}
1506 1508
1507#endif 1509#endif
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h
index 4647ae2756..add3989061 100644
--- a/apps/recorder/radio.h
+++ b/apps/recorder/radio.h
@@ -26,7 +26,7 @@
26#if CONFIG_TUNER 26#if CONFIG_TUNER
27void radio_load_presets(char *filename); 27void radio_load_presets(char *filename);
28void radio_init(void); 28void radio_init(void);
29bool radio_screen(void); 29int radio_screen(void);
30void radio_start(void); 30void radio_start(void);
31void radio_pause(void); 31void radio_pause(void);
32void radio_stop(void); 32void radio_stop(void);
diff --git a/apps/root_menu.c b/apps/root_menu.c
new file mode 100644
index 0000000000..0f2153b03b
--- /dev/null
+++ b/apps/root_menu.c
@@ -0,0 +1,361 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
9 *
10 * Copyright (C) 2007 Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <stdbool.h>
23#include "config.h"
24#include "menu.h"
25#include "root_menu.h"
26#include "lang.h"
27#include "settings.h"
28#include "kernel.h"
29#include "debug.h"
30#include "misc.h"
31#include "rolo.h"
32#include "backdrop.h"
33#include "talk.h"
34#include "audio.h"
35
36/* gui api */
37#include "list.h"
38#include "statusbar.h"
39#include "splash.h"
40#include "buttonbar.h"
41#include "textarea.h"
42#include "action.h"
43#include "yesno.h"
44
45#include "main_menu.h"
46#include "tree.h"
47#include "radio.h"
48#ifdef HAVE_RECORDING
49#include "recording.h"
50#endif
51#include "gwps-common.h"
52#include "bookmark.h"
53#include "tagtree.h"
54#include "menus/exported_menus.h"
55
56struct root_items {
57 int (*function)(void* param);
58 void* param;
59};
60static int last_screen = GO_TO_ROOT; /* unfortunatly needed so we can resume
61 or goto current track based on previous
62 screen */
63static int browser(void* param)
64{
65 int ret_val;
66 struct tree_context* tc = tree_get_context();
67 int filter = SHOW_SUPPORTED;
68 char folder[MAX_PATH] = "/";
69 /* stuff needed to remember position in file browser */
70 static char last_folder[MAX_PATH] = "/";
71 /* and stuff for the database browser */
72 static int last_db_dirlevel = 0;
73
74 switch ((int)param)
75 {
76 case GO_TO_FILEBROWSER:
77 filter = global_settings.dirfilter;
78 if (global_settings.browse_current &&
79 last_screen == GO_TO_WPS && audio_status() &&
80 wps_state.current_track_path[0] != '\0')
81 {
82 snprintf(folder, MAX_PATH, "%s", wps_state.current_track_path);
83 }
84 else
85 snprintf(folder, MAX_PATH, "%s/", last_folder);
86 break;
87 case GO_TO_DBBROWSER:
88 if (!tagcache_is_usable())
89 {
90 gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
91 return GO_TO_PREVIOUS;
92 }
93 filter = SHOW_ID3DB;
94 tc->dirlevel = last_db_dirlevel;
95 break;
96 case GO_TO_BROWSEPLUGINS:
97 filter = SHOW_PLUGINS;
98 snprintf(folder, MAX_PATH, "%s/", PLUGIN_DIR);
99 break;
100 }
101 ret_val = rockbox_browse(folder, filter);
102 switch ((int)param)
103 {
104 case GO_TO_FILEBROWSER:
105 strcpy(last_folder, tc->currdir);
106 break;
107 case GO_TO_DBBROWSER:
108 last_db_dirlevel = tc->dirlevel;
109 break;
110 }
111 return ret_val;
112}
113
114static int menu(void* param)
115{
116 (void)param;
117 return main_menu();
118
119}
120#ifdef HAVE_RECORDING
121static int recscrn(void* param)
122{
123 (void)param;
124 recording_screen(false);
125 return GO_TO_ROOT;
126}
127#endif
128static int wpsscrn(void* param)
129{
130 int ret_val = GO_TO_PREVIOUS;
131 (void)param;
132 if (audio_status())
133 {
134 ret_val = gui_wps_show();
135 }
136 else if ( global_status.resume_index != -1 )
137 {
138 DEBUGF("Resume index %X offset %X\n",
139 global_status.resume_index,
140 global_status.resume_offset);
141
142#ifdef HAVE_ALARM_MOD
143 if ( rtc_check_alarm_started(true) ) {
144 rtc_enable_alarm(false);
145 }
146#endif
147
148 if (playlist_resume() != -1)
149 {
150 playlist_start(global_status.resume_index,
151 global_status.resume_offset);
152 ret_val = gui_wps_show();
153 }
154 }
155 else
156 {
157 gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
158 }
159#if LCD_DEPTH > 1
160 show_main_backdrop();
161#endif
162 return ret_val;
163}
164#if CONFIG_TUNER
165static int radio(void* param)
166{
167 (void)param;
168 radio_screen();
169 return GO_TO_ROOT;
170}
171#endif
172
173static int load_bmarks(void* param)
174{
175 (void)param;
176 bookmark_mrb_load();
177 return GO_TO_PREVIOUS;
178}
179
180static const struct root_items items[] = {
181 [GO_TO_FILEBROWSER] = { browser, (void*)GO_TO_FILEBROWSER },
182 [GO_TO_DBBROWSER] = { browser, (void*)GO_TO_DBBROWSER },
183 [GO_TO_WPS] = { wpsscrn, NULL },
184 [GO_TO_MAINMENU] = { menu, NULL },
185
186#ifdef HAVE_RECORDING
187 [GO_TO_RECSCREEN] = { recscrn, NULL },
188#endif
189
190#if CONFIG_TUNER
191 [GO_TO_FM] = { radio, NULL },
192#endif
193
194 [GO_TO_RECENTBMARKS] = { load_bmarks, NULL },
195 [GO_TO_BROWSEPLUGINS] = { browser, (void*)GO_TO_BROWSEPLUGINS },
196
197};
198static const int nb_items = sizeof(items)/sizeof(*items);
199
200#ifdef BOOTFILE
201extern bool boot_changed; /* from tree.c */
202static void check_boot(void)
203{
204 if (boot_changed) {
205 char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)};
206 struct text_message message={lines, 2};
207 if(gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
208 rolo_load("/" BOOTFILE);
209 boot_changed = false;
210 }
211}
212#else
213# define check_boot()
214#endif
215int item_callback(int action, const struct menu_item_ex *this_item) ;
216
217MENUITEM_RETURNVALUE(file_browser, ID2P(LANG_DIR_BROWSER), GO_TO_FILEBROWSER,
218 NULL, bitmap_icons_6x8[Icon_file_view_menu]);
219MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER,
220 NULL, bitmap_icons_6x8[Icon_Audio]);
221MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS,
222 NULL, bitmap_icons_6x8[Icon_Plugin]);
223char *get_wps_item_name(int selected_item, void * data, char *buffer)
224{
225 (void)selected_item; (void)data; (void)buffer;
226 if (audio_status())
227 return str(LANG_NOW_PLAYING);
228 return str(LANG_RESUME_PLAYBACK);
229}
230MENUITEM_RETURNVALUE_DYNTEXT(wps_item, GO_TO_WPS, NULL, get_wps_item_name,
231 NULL, bitmap_icons_6x8[Icon_Playback_menu]);
232#ifdef HAVE_RECORDING
233MENUITEM_RETURNVALUE(rec, ID2P(LANG_RECORDING_MENU), GO_TO_RECSCREEN,
234 NULL, bitmap_icons_6x8[Icon_Recording]);
235#endif
236#if CONFIG_TUNER
237MENUITEM_RETURNVALUE(fm, ID2P(LANG_FM_RADIO), GO_TO_FM,
238 item_callback, bitmap_icons_6x8[Icon_Radio_screen]);
239#endif
240MENUITEM_RETURNVALUE(menu_, ID2P(LANG_SETTINGS_MENU), GO_TO_MAINMENU,
241 NULL, bitmap_icons_6x8[Icon_Submenu_Entered]);
242MENUITEM_RETURNVALUE(bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
243 GO_TO_RECENTBMARKS, item_callback,
244 bitmap_icons_6x8[Icon_Bookmark]);
245#ifdef HAVE_LCD_CHARCELLS
246static int do_shutdown(void)
247{
248 sys_poweroff();
249 return 0;
250}
251MENUITEM_FUNCTION(do_shutdown_item, ID2P(LANG_SHUTDOWN), do_shutdown, NULL, NOICON);
252#endif
253MAKE_MENU(root_menu_, ID2P(LANG_ROCKBOX_TITLE),
254 NULL, bitmap_icons_6x8[Icon_Rockbox],
255 &bookmarks, &file_browser, &db_browser,
256 &wps_item, &menu_,
257#ifdef HAVE_RECORDING
258 &rec,
259#endif
260#if CONFIG_TUNER
261 &fm,
262#endif
263 &playlist_options, &rocks_browser, &info_menu
264
265#ifdef HAVE_LCD_CHARCELLS
266 ,&do_shutdown_item
267#endif
268 );
269
270int item_callback(int action, const struct menu_item_ex *this_item)
271{
272 switch (action)
273 {
274 case ACTION_REQUEST_MENUITEM:
275#if CONFIG_TUNER
276 if (this_item == &fm)
277 {
278 if (radio_hardware_present() == 0)
279 return ACTION_EXIT_MENUITEM;
280 }
281 else
282#endif
283 if (this_item == &bookmarks)
284 {
285 if (global_settings.usemrb == 0)
286 return ACTION_EXIT_MENUITEM;
287 }
288 break;
289 }
290 return action;
291}
292
293void root_menu(void)
294{
295 int previous_browser = GO_TO_FILEBROWSER;
296 int previous_music = GO_TO_WPS;
297 int ret_val = GO_TO_ROOT;
298 int this_screen = GO_TO_ROOT;
299 int selected = 0;
300
301 if (global_settings.start_in_screen == 0)
302 ret_val = (int)global_status.last_screen;
303 else ret_val = global_settings.start_in_screen - 2;
304
305 while (true)
306 {
307 switch (ret_val)
308 {
309 case GO_TO_ROOT:
310 ret_val = do_menu(&root_menu_, &selected);
311 /* As long as MENU_ATTACHED_USB == GO_TO_ROOT this works */
312 if (ret_val == MENU_ATTACHED_USB)
313 {
314 check_boot();
315 continue;
316 }
317
318 if (ret_val == GO_TO_PREVIOUS_MUSIC)
319 ret_val = previous_music;
320 last_screen = GO_TO_ROOT;
321 break;
322 case GO_TO_PREVIOUS:
323 ret_val = last_screen;
324 if (last_screen == GO_TO_ROOT)
325 continue;
326 break;
327 case GO_TO_PREVIOUS_BROWSER:
328 if ((previous_browser == GO_TO_DBBROWSER) &&
329 !tagcache_is_usable())
330 ret_val = GO_TO_FILEBROWSER;
331 else
332 ret_val = previous_browser;
333 break;
334 case GO_TO_PREVIOUS_MUSIC:
335 ret_val = previous_music;
336 break;
337 }
338 this_screen = ret_val;
339
340 if (this_screen == GO_TO_FILEBROWSER)
341 previous_browser = GO_TO_FILEBROWSER;
342 else if (this_screen == GO_TO_DBBROWSER)
343 previous_browser = GO_TO_DBBROWSER;
344 else if (this_screen == GO_TO_WPS)
345 previous_music = GO_TO_WPS;
346#if CONFIG_TUNER
347 else if (this_screen == GO_TO_FM)
348 previous_music = GO_TO_FM;
349#endif
350
351 /* set the global_status.last_screen before entering,
352 if we dont we will always return to the wrong screen on boot */
353 global_status.last_screen = (char)this_screen;
354 status_save();
355 action_signalscreenchange();
356 ret_val = items[this_screen].function(items[this_screen].param);
357 if (ret_val != GO_TO_PREVIOUS)
358 last_screen = this_screen;
359 }
360 return;
361}
diff --git a/apps/root_menu.h b/apps/root_menu.h
new file mode 100644
index 0000000000..9b07e58044
--- /dev/null
+++ b/apps/root_menu.h
@@ -0,0 +1,44 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id: main.c 12101 2007-01-24 02:19:22Z jdgordon $
9*
10* Copyright (C) 2007 Jonathan Gordon
11*
12* All files in this archive are subject to the GNU General Public License.
13* See the file COPYING in the source tree root for full license agreement.
14*
15* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16* KIND, either express or implied.
17*
18****************************************************************************/
19#include "config.h"
20void root_menu(void);
21
22enum {
23 GO_TO_PREVIOUS_MUSIC = -4,
24 GO_TO_PREVIOUS_BROWSER = -3,
25 GO_TO_PREVIOUS = -2,
26 GO_TO_ROOT = -1,
27 GO_TO_FILEBROWSER = 0,
28 GO_TO_DBBROWSER,
29 GO_TO_WPS,
30 GO_TO_MAINMENU,
31#ifdef HAVE_RECORDING
32 GO_TO_RECSCREEN,
33#endif
34#ifdef CONFIG_TUNER
35 GO_TO_FM,
36#endif
37 GO_TO_RECENTBMARKS,
38 GO_TO_BROWSEPLUGINS,
39 /* Do Not add any items above here unless you want it to be able to
40 be the "start screen" after a boot up. The setting in settings_list.c
41 will need editing if this is the case. */
42};
43
44extern const struct menu_item_ex root_menu_;
diff --git a/apps/screens.c b/apps/screens.c
index 54904ea144..9835d28d8f 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -654,9 +654,6 @@ bool quick_screen_quick(int button_enter)
654 [SHOW_SUPPORTED]={ STR(LANG_SYSFONT_FILTER_SUPPORTED) }, 654 [SHOW_SUPPORTED]={ STR(LANG_SYSFONT_FILTER_SUPPORTED) },
655 [SHOW_MUSIC]={ STR(LANG_SYSFONT_FILTER_MUSIC) }, 655 [SHOW_MUSIC]={ STR(LANG_SYSFONT_FILTER_MUSIC) },
656 [SHOW_PLAYLIST]={ STR(LANG_SYSFONT_FILTER_PLAYLIST) }, 656 [SHOW_PLAYLIST]={ STR(LANG_SYSFONT_FILTER_PLAYLIST) },
657#ifdef HAVE_TAGCACHE
658 [SHOW_ID3DB]={ STR(LANG_SYSFONT_FILTER_ID3DB) }
659#endif
660 }; 657 };
661 static const struct opt_items right_items[] = { 658 static const struct opt_items right_items[] = {
662 [REPEAT_OFF]={ STR(LANG_SYSFONT_OFF) }, 659 [REPEAT_OFF]={ STR(LANG_SYSFONT_OFF) },
diff --git a/apps/settings.h b/apps/settings.h
index f306f4b0de..b83b120a37 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -277,6 +277,7 @@ struct system_status
277 int last_frequency; /* Last frequency for resuming, in FREQ_STEP units, 277 int last_frequency; /* Last frequency for resuming, in FREQ_STEP units,
278 relative to MIN_FREQ */ 278 relative to MIN_FREQ */
279#endif 279#endif
280 char last_screen;
280}; 281};
281 282
282struct user_settings 283struct user_settings
@@ -684,6 +685,7 @@ struct user_settings
684 /* Encoder Settings End */ 685 /* Encoder Settings End */
685#endif /* CONFIG_CODEC == SWCODEC */ 686#endif /* CONFIG_CODEC == SWCODEC */
686 bool cuesheet; 687 bool cuesheet;
688 int start_in_screen;
687}; 689};
688 690
689/** global variables **/ 691/** global variables **/
diff --git a/apps/settings_list.c b/apps/settings_list.c
index b1c78dec68..a7e588d48d 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -617,15 +617,8 @@ const struct settings_list settings[] = {
617#endif /* HAVE_MMC */ 617#endif /* HAVE_MMC */
618 /* browser */ 618 /* browser */
619 CHOICE_SETTING(0, dirfilter, LANG_FILTER, SHOW_SUPPORTED, "show files", 619 CHOICE_SETTING(0, dirfilter, LANG_FILTER, SHOW_SUPPORTED, "show files",
620#ifndef HAVE_TAGCACHE
621 "all,supported,music,playlists", NULL, 4, ID2P(LANG_FILTER_ALL), 620 "all,supported,music,playlists", NULL, 4, ID2P(LANG_FILTER_ALL),
622 ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST) 621 ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC), ID2P(LANG_FILTER_PLAYLIST)),
623#else
624 "all,supported,music,playlists,id3 database", NULL, 5, ID2P(LANG_FILTER_ALL),
625 ID2P(LANG_FILTER_SUPPORTED), ID2P(LANG_FILTER_MUSIC),
626 ID2P(LANG_FILTER_PLAYLIST), ID2P(LANG_FILTER_ID3DB)
627#endif
628 ),
629 OFFON_SETTING(0,sort_case,LANG_SORT_CASE,false,"sort case",NULL), 622 OFFON_SETTING(0,sort_case,LANG_SORT_CASE,false,"sort case",NULL),
630 OFFON_SETTING(0,browse_current,LANG_FOLLOW,false,"follow playlist",NULL), 623 OFFON_SETTING(0,browse_current,LANG_FOLLOW,false,"follow playlist",NULL),
631 OFFON_SETTING(0,playlist_viewer_icons,LANG_SHOW_ICONS,true, 624 OFFON_SETTING(0,playlist_viewer_icons,LANG_SHOW_ICONS,true,
@@ -1089,6 +1082,34 @@ const struct settings_list settings[] = {
1089#endif 1082#endif
1090#endif 1083#endif
1091 OFFON_SETTING(0,cuesheet,LANG_CUESHEET_ENABLE,false,"cuesheet support", NULL), 1084 OFFON_SETTING(0,cuesheet,LANG_CUESHEET_ENABLE,false,"cuesheet support", NULL),
1085 CHOICE_SETTING(0, start_in_screen, LANG_START_SCREEN, 1,
1086 "start in screen", "previous,root,files,db,wps,menu,"
1087#ifdef HAVE_RECORDING
1088 ",recording"
1089#endif
1090#if CONFIG_TUNER
1091 ",radio"
1092#endif
1093 ,NULL,
1094#if defined(HAVE_RECORDING) && CONFIG_TUNER
1095 8,
1096#elif defined(HAVE_RECORDING) || CONFIG_TUNER /* only one of them */
1097 7,
1098#else
1099 6,
1100#endif
1101 ID2P(LANG_PREVIOUS_SCREEN), ID2P(LANG_MAIN_MENU),
1102 ID2P(LANG_DIR_BROWSER), ID2P(LANG_TAGCACHE),
1103 ID2P(LANG_RESUME_PLAYBACK), ID2P(LANG_SETTINGS_MENU)
1104#ifdef HAVE_RECORDING
1105 ,ID2P(LANG_RECORDING)
1106#endif
1107#if CONFIG_TUNER
1108 ,ID2P(LANG_FM_RADIO)
1109#endif
1110
1111 ),
1112 SYSTEM_SETTING(NVRAM(1),last_screen,-1),
1092}; 1113};
1093 1114
1094const int nb_settings = sizeof(settings)/sizeof(*settings); 1115const int nb_settings = sizeof(settings)/sizeof(*settings);
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index dc6da57a1f..d7b7b80d6e 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -424,12 +424,6 @@ static bool recdirectory(void)
424 names, 2, NULL ); 424 names, 2, NULL );
425} 425}
426 426
427static bool reconstartup(void)
428{
429 return set_bool(str(LANG_RECORD_STARTUP),
430 &global_settings.rec_startup);
431}
432
433#if CONFIG_BACKLIGHT 427#if CONFIG_BACKLIGHT
434static bool cliplight(void) 428static bool cliplight(void)
435{ 429{
@@ -940,7 +934,6 @@ bool recording_menu(bool no_source)
940 { ID2P(LANG_RECORD_TIMESPLIT), filesplitoptionsmenu }, 934 { ID2P(LANG_RECORD_TIMESPLIT), filesplitoptionsmenu },
941 { ID2P(LANG_RECORD_PRERECORD_TIME), recprerecord }, 935 { ID2P(LANG_RECORD_PRERECORD_TIME), recprerecord },
942 { ID2P(LANG_RECORD_DIRECTORY), recdirectory }, 936 { ID2P(LANG_RECORD_DIRECTORY), recdirectory },
943 { ID2P(LANG_RECORD_STARTUP), reconstartup },
944#if CONFIG_BACKLIGHT 937#if CONFIG_BACKLIGHT
945 { ID2P(LANG_CLIP_LIGHT), cliplight }, 938 { ID2P(LANG_CLIP_LIGHT), cliplight },
946#endif 939#endif
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 1d87f29b50..a0c6d66541 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -3953,7 +3953,10 @@ bool tagcache_is_initialized(void)
3953{ 3953{
3954 return tc_stat.initialized; 3954 return tc_stat.initialized;
3955} 3955}
3956 3956bool tagcache_is_usable(void)
3957{
3958 return tc_stat.initialized && tc_stat.ready;
3959}
3957int tagcache_get_commit_step(void) 3960int tagcache_get_commit_step(void)
3958{ 3961{
3959 return tc_stat.commit_step; 3962 return tc_stat.commit_step;
diff --git a/apps/tagcache.h b/apps/tagcache.h
index ea8b06f4fa..7e9a42dfa7 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -182,6 +182,7 @@ void tagcache_unload_ramcache(void);
182#endif 182#endif
183void tagcache_init(void); 183void tagcache_init(void);
184bool tagcache_is_initialized(void); 184bool tagcache_is_initialized(void);
185bool tagcache_is_usable(void);
185void tagcache_start_scan(void); 186void tagcache_start_scan(void);
186void tagcache_stop_scan(void); 187void tagcache_stop_scan(void);
187bool tagcache_update(void); 188bool tagcache_update(void);
diff --git a/apps/tree.c b/apps/tree.c
index 78fb1db76d..f830e3eb26 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -79,6 +79,7 @@
79#include "textarea.h" 79#include "textarea.h"
80#include "action.h" 80#include "action.h"
81 81
82#include "root_menu.h"
82 83
83#if LCD_DEPTH > 1 84#if LCD_DEPTH > 1
84#include "backdrop.h" 85#include "backdrop.h"
@@ -160,9 +161,10 @@ static int max_files = 0;
160static bool reload_dir = false; 161static bool reload_dir = false;
161 162
162static bool start_wps = false; 163static bool start_wps = false;
163static bool dirbrowse(void);
164static int curr_context = false;/* id3db or tree*/ 164static int curr_context = false;/* id3db or tree*/
165 165
166int dirbrowse(void);
167
166/* 168/*
167 * removes the extension of filename (if it doesn't start with a .) 169 * removes the extension of filename (if it doesn't start with a .)
168 * puts the result in buffer 170 * puts the result in buffer
@@ -272,13 +274,8 @@ void browse_root(void)
272 gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1); 274 gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1);
273 gui_synclist_set_icon_callback(&tree_lists, 275 gui_synclist_set_icon_callback(&tree_lists,
274 global_settings.show_icons?&tree_get_fileicon:NULL); 276 global_settings.show_icons?&tree_get_fileicon:NULL);
275#ifndef SIMULATOR 277 /* not the best place for this call... but... */
276 dirbrowse(); 278 root_menu();
277#else
278 if (!dirbrowse()) {
279 DEBUGF("No filesystem found. Have you forgotten to create it?\n");
280 }
281#endif
282} 279}
283 280
284void tree_get_filetypes(const struct filetype** types, int* count) 281void tree_get_filetypes(const struct filetype** types, int* count)
@@ -478,54 +475,6 @@ void reload_directory(void)
478 reload_dir = true; 475 reload_dir = true;
479} 476}
480 477
481static void start_resume(bool just_powered_on)
482{
483 bool do_resume = false;
484 if ( global_status.resume_index != -1 ) {
485 DEBUGF("Resume index %X offset %X\n",
486 global_status.resume_index,
487 global_status.resume_offset);
488
489#ifdef HAVE_RTC_ALARM
490 if ( rtc_check_alarm_started(true) ) {
491 rtc_enable_alarm(false);
492 do_resume = true;
493 }
494#endif
495
496 /* always resume? */
497 if ( global_settings.resume || ! just_powered_on)
498#ifdef HAVE_HEADPHONE_DETECTION
499 {
500 if ( just_powered_on )
501 {
502 if ( !global_settings.unplug_autoresume
503 || headphones_inserted() )
504 do_resume = true;
505 }
506 else
507 do_resume = true;
508 }
509#else
510 do_resume = true;
511#endif
512
513 if (! do_resume) return;
514
515 if (playlist_resume() != -1)
516 {
517 playlist_start(global_status.resume_index,
518 global_status.resume_offset);
519
520 start_wps = true;
521 }
522 else return;
523 }
524 else if (! just_powered_on) {
525 gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME));
526 }
527}
528
529/* Selects a file and update tree context properly */ 478/* Selects a file and update tree context properly */
530void set_current_file(char *path) 479void set_current_file(char *path)
531{ 480{
@@ -568,10 +517,7 @@ void set_current_file(char *path)
568 tc.selected_item_history[tc.dirlevel] = -1; 517 tc.selected_item_history[tc.dirlevel] = -1;
569 518
570 /* use '/' to calculate dirlevel */ 519 /* use '/' to calculate dirlevel */
571 /* FIXME : strlen(path) : crazy oO better to store it at 520 for (i = 1; path[i] != '\0'; i++)
572 the beginning */
573 int path_len = strlen(path) + 1;
574 for (i = 1; i < path_len; i++)
575 { 521 {
576 if (path[i] == '/') 522 if (path[i] == '/')
577 { 523 {
@@ -580,9 +526,13 @@ void set_current_file(char *path)
580 } 526 }
581 } 527 }
582 } 528 }
529 if (ft_load(&tc, NULL) >= 0)
530 {
531 tc.selected_item = tree_get_file_position(lastfile);
532 }
583} 533}
584 534
585#ifdef HAVE_TAGCACHE 535#if defined(HAVE_TAGCACHE) && defined(HAVE_QUICKSCREEN)
586static bool check_changed_id3mode(bool currmode) 536static bool check_changed_id3mode(bool currmode)
587{ 537{
588 if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) { 538 if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) {
@@ -605,7 +555,7 @@ static bool check_changed_id3mode(bool currmode)
605#endif 555#endif
606 556
607/* main loop, handles key events */ 557/* main loop, handles key events */
608static bool dirbrowse(void) 558int dirbrowse()
609{ 559{
610 int numentries=0; 560 int numentries=0;
611 char buf[MAX_PATH]; 561 char buf[MAX_PATH];
@@ -627,8 +577,8 @@ static bool dirbrowse(void)
627 else 577 else
628#endif 578#endif
629 curr_context=CONTEXT_TREE; 579 curr_context=CONTEXT_TREE;
630 tc.selected_item = 0; 580 if (tc.selected_item < 0)
631 tc.dirlevel=0; 581 tc.selected_item = 0;
632#ifdef HAVE_TAGCACHE 582#ifdef HAVE_TAGCACHE
633 tc.firstpos=0; 583 tc.firstpos=0;
634 lasttable = -1; 584 lasttable = -1;
@@ -636,43 +586,22 @@ static bool dirbrowse(void)
636 lastfirstpos = 0; 586 lastfirstpos = 0;
637#endif 587#endif
638 588
639 if (*tc.dirfilter < NUM_FILTER_MODES) { 589 start_wps = false;
640#ifdef HAVE_RECORDING 590 numentries = update_dir();
641#ifndef SIMULATOR 591 if (numentries == -1)
642 if (global_settings.rec_startup) { 592 return false; /* currdir is not a directory */
643 /* We fake being in the menu structure by calling
644 the appropriate parent when we drop out of each screen */
645#if CONFIG_CODEC == SWCODEC
646 /* Put in a 1 sec pause to slow bootup or the recording codecs
647 won't initialize */
648 sleep(HZ);
649#endif
650 recording_screen(false);
651 rec_menu();
652 main_menu();
653 }
654 else
655#endif
656#endif
657 start_resume(true);
658
659 }
660 /* If we don't need to show the wps, draw the dir */
661 if (!start_wps) {
662 numentries = update_dir();
663 if (numentries == -1)
664 return false; /* currdir is not a directory */
665 593
666 if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0) 594 if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0)
667 { 595 {
668 gui_syncsplash(HZ*2, true, str(LANG_NO_FILES)); 596 gui_syncsplash(HZ*2, true, str(LANG_NO_FILES));
669 return false; /* No files found for rockbox_browser() */ 597 return false; /* No files found for rockbox_browser() */
670 }
671 } 598 }
672 599
673 while(1) { 600 while(1) {
674 struct entry *dircache = tc.dircache; 601 struct entry *dircache = tc.dircache;
675 bool restore = false; 602 bool restore = false;
603 if (tc.dirlevel < 0)
604 tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
676#ifdef BOOTFILE 605#ifdef BOOTFILE
677 if (boot_changed) { 606 if (boot_changed) {
678 char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)}; 607 char *lines[]={str(LANG_BOOT_CHANGED), str(LANG_REBOOT_NOW)};
@@ -715,10 +644,12 @@ static bool dirbrowse(void)
715 exit_func = true; 644 exit_func = true;
716 break; 645 break;
717 } 646 }
718 /* if we are in /, nothing to do */ 647 if ((*tc.dirfilter == SHOW_ID3DB && tc.dirlevel == 0) ||
719 if (tc.dirlevel == 0 && !strcmp(currdir,"/")) 648 ((*tc.dirfilter != SHOW_ID3DB && !strcmp(currdir,"/"))))
720 break; 649 {
721 650 break; /* do nothing */
651 }
652
722#ifdef HAVE_TAGCACHE 653#ifdef HAVE_TAGCACHE
723 if (id3db) 654 if (id3db)
724 tagtree_exit(&tc); 655 tagtree_exit(&tc);
@@ -772,37 +703,17 @@ static bool dirbrowse(void)
772 /* don't enter menu from plugin browser */ 703 /* don't enter menu from plugin browser */
773 if (*tc.dirfilter < NUM_FILTER_MODES) 704 if (*tc.dirfilter < NUM_FILTER_MODES)
774 { 705 {
775 int i; 706 return GO_TO_ROOT;
776 FOR_NB_SCREENS(i)
777 screens[i].stop_scroll();
778 action_signalscreenchange();
779 if (main_menu())
780 reload_dir = true;
781 restore = true;
782
783#ifdef HAVE_TAGCACHE
784 id3db = check_changed_id3mode(id3db);
785 if(id3db)
786 reload_dir = true;
787#endif
788 } 707 }
789 else /* use it as a quick exit instead */ 708 else /* use it as a quick exit instead */
790 exit_func = true; 709 return GO_TO_PREVIOUS;
791 break; 710 break;
792 711
793 case ACTION_TREE_WPS: 712 case ACTION_TREE_WPS:
794 /* don't enter wps from plugin browser etc */ 713 /* don't enter wps from plugin browser etc */
795 if (*tc.dirfilter < NUM_FILTER_MODES) 714 if (*tc.dirfilter < NUM_FILTER_MODES)
796 { 715 {
797 if (audio_status() & AUDIO_STATUS_PLAY) 716 return GO_TO_PREVIOUS_MUSIC;
798 {
799 start_wps=true;
800 }
801 else
802 {
803 start_resume(false);
804 restore = true;
805 }
806 } 717 }
807 break; 718 break;
808#ifdef HAVE_QUICKSCREEN 719#ifdef HAVE_QUICKSCREEN
@@ -869,6 +780,9 @@ static bool dirbrowse(void)
869 } 780 }
870 switch (onplay_result) 781 switch (onplay_result)
871 { 782 {
783 case ONPLAY_MAINMENU:
784 return GO_TO_ROOT;
785
872 case ONPLAY_OK: 786 case ONPLAY_OK:
873 restore = true; 787 restore = true;
874 break; 788 break;
@@ -878,7 +792,7 @@ static bool dirbrowse(void)
878 break; 792 break;
879 793
880 case ONPLAY_START_PLAY: 794 case ONPLAY_START_PLAY:
881 start_wps = true; 795 return GO_TO_WPS;
882 break; 796 break;
883 } 797 }
884 break; 798 break;
@@ -952,37 +866,13 @@ static bool dirbrowse(void)
952 } 866 }
953 break; 867 break;
954 } 868 }
955 869 if (start_wps)
870 return GO_TO_WPS;
956 if ( button ) 871 if ( button )
957 { 872 {
958 ata_spin(); 873 ata_spin();
959 } 874 }
960 875
961 if (start_wps && audio_status() )
962 {
963 int i;
964
965 FOR_NB_SCREENS(i)
966 screens[i].stop_scroll();
967
968 if (gui_wps_show() == SYS_USB_CONNECTED)
969 reload_dir = true;
970#ifdef HAVE_HOTSWAP
971 else
972#ifdef HAVE_TAGCACHE
973 if (!id3db) /* Try reload to catch 'no longer valid' case. */
974#endif
975 reload_dir = true;
976#endif
977#if LCD_DEPTH > 1
978 show_main_backdrop();
979#endif
980#ifdef HAVE_TAGCACHE
981 id3db = check_changed_id3mode(id3db);
982#endif
983 restore = true;
984 start_wps=false;
985 }
986 876
987 check_rescan: 877 check_rescan:
988 /* do we need to rescan dir? */ 878 /* do we need to rescan dir? */
@@ -1016,7 +906,7 @@ static bool dirbrowse(void)
1016 } 906 }
1017 907
1018 if (exit_func) 908 if (exit_func)
1019 break; 909 return GO_TO_PREVIOUS;
1020 910
1021 if (restore || reload_dir) { 911 if (restore || reload_dir) {
1022 /* restore display */ 912 /* restore display */
@@ -1252,24 +1142,39 @@ bool create_playlist(void)
1252 return true; 1142 return true;
1253} 1143}
1254 1144
1255bool rockbox_browse(const char *root, int dirfilter) 1145int rockbox_browse(const char *root, int dirfilter)
1256{ 1146{
1257 static struct tree_context backup; 1147 int ret_val = 0;
1258 int last_context; 1148 int *last_filter = tc.dirfilter;
1259
1260 backup = tc;
1261 reload_dir = true;
1262 memcpy(tc.currdir, root, sizeof(tc.currdir));
1263 start_wps = false;
1264 tc.dirfilter = &dirfilter; 1149 tc.dirfilter = &dirfilter;
1265 last_context = curr_context;
1266 1150
1267 dirbrowse(); 1151 reload_dir = true;
1268 1152 if (dirfilter >= NUM_FILTER_MODES)
1269 tc = backup; 1153 {
1270 curr_context = last_context; 1154 static struct tree_context backup;
1271 1155 int last_context;
1272 return false; 1156
1157 backup = tc;
1158 tc.dirlevel = 0;
1159 memcpy(tc.currdir, root, sizeof(tc.currdir));
1160 start_wps = false;
1161 last_context = curr_context;
1162
1163 ret_val = dirbrowse();
1164 tc = backup;
1165 curr_context = last_context;
1166 }
1167 else
1168 {
1169 static char buf[MAX_PATH];
1170 if (dirfilter != SHOW_ID3DB)
1171 tc.dirfilter = &global_settings.dirfilter;
1172 strcpy(buf,root);
1173 set_current_file(buf);
1174 ret_val = dirbrowse();
1175 }
1176 tc.dirfilter = last_filter;
1177 return ret_val;
1273} 1178}
1274 1179
1275void tree_init(void) 1180void tree_init(void)
diff --git a/apps/tree.h b/apps/tree.h
index 110fc09f0c..7b202e0fbc 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -101,7 +101,7 @@ void tree_get_filetypes(const struct filetype**, int*);
101void tree_init(void); 101void tree_init(void);
102void browse_root(void); 102void browse_root(void);
103void set_current_file(char *path); 103void set_current_file(char *path);
104bool rockbox_browse(const char *root, int dirfilter); 104int rockbox_browse(const char *root, int dirfilter);
105bool create_playlist(void); 105bool create_playlist(void);
106void resume_directory(const char *dir); 106void resume_directory(const char *dir);
107char *getcwd(char *buf, int size); 107char *getcwd(char *buf, int size);