summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-02-08 04:33:41 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-02-08 04:33:41 +0000
commit4718a1e7526b3e7601a51c9bf55395d1950b1ffe (patch)
treec9a806f391a0d3fe3138c888c476f1ec727a6608
parent092d355c3447a3c46d21bb7dbdf3f726ab27ec1d (diff)
downloadrockbox-4718a1e7526b3e7601a51c9bf55395d1950b1ffe.tar.gz
rockbox-4718a1e7526b3e7601a51c9bf55395d1950b1ffe.zip
beginning of the new menu system. This commit shouldnt break anything,
but comming ones might.. report bugs in http://forums.rockbox.org/index.php?topic=8703.0 and more info at http://www.rockbox.org/twiki/bin/view/Main/SettingsRecode git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12227 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/SOURCES8
-rw-r--r--apps/action.h4
-rw-r--r--apps/main_menu.c16
-rw-r--r--apps/menu.c336
-rw-r--r--apps/menu.h178
-rw-r--r--apps/menus/display_menu.c32
-rw-r--r--apps/menus/exported_menus.h40
-rw-r--r--apps/menus/main_menu.c125
-rw-r--r--apps/menus/playlist_menu.c32
-rw-r--r--apps/menus/recording_menu.c41
-rw-r--r--apps/menus/recording_settings_menu.c33
-rw-r--r--apps/menus/settings_menu.c33
-rw-r--r--apps/menus/sound_menu.c32
-rw-r--r--apps/recorder/recording.h1
-rw-r--r--apps/settings.c73
-rw-r--r--apps/settings.h4
-rw-r--r--apps/settings_list.c56
-rw-r--r--apps/settings_list.h33
-rw-r--r--apps/settings_menu.c4
-rw-r--r--apps/sound_menu.c51
-rw-r--r--apps/sound_menu.h1
21 files changed, 951 insertions, 182 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 2304ee7031..d47e2bdd29 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -11,6 +11,14 @@ language.c
11main.c 11main.c
12main_menu.c 12main_menu.c
13menu.c 13menu.c
14menus/display_menu.c
15menus/main_menu.c
16menus/playlist_menu.c
17#ifdef HAVE_RECORDING
18menus/recording_menu.c
19#endif
20menus/settings_menu.c
21menus/sound_menu.c
14misc.c 22misc.c
15onplay.c 23onplay.c
16playlist.c 24playlist.c
diff --git a/apps/action.h b/apps/action.h
index 5a8168ea80..9519bd0fc7 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -154,6 +154,10 @@ enum {
154 ACTION_REC_F3, 154 ACTION_REC_F3,
155 155
156 /* main menu */ 156 /* main menu */
157 ACTION_REQUEST_MENUITEM,
158 ACTION_EXIT_MENUITEM,
159 ACTION_ENTER_MENUITEM,
160 ACTION_MENU_WPS,
157 161
158 /* id3db */ 162 /* id3db */
159 163
diff --git a/apps/main_menu.c b/apps/main_menu.c
index 7e20656dc9..078e7669f2 100644
--- a/apps/main_menu.c
+++ b/apps/main_menu.c
@@ -281,16 +281,6 @@ static bool show_info(void)
281 return false; 281 return false;
282} 282}
283 283
284static bool plugin_browse(void)
285{
286 return rockbox_browse(PLUGIN_DIR, SHOW_PLUGINS);
287}
288
289static bool custom_theme_browse(void)
290{
291 return rockbox_browse(THEME_DIR, SHOW_CFG);
292}
293
294#ifdef HAVE_RECORDING 284#ifdef HAVE_RECORDING
295 285
296static bool rec_menu_recording_screen(void) 286static bool rec_menu_recording_screen(void)
@@ -340,7 +330,7 @@ bool rec_menu(void)
340} 330}
341#endif 331#endif
342 332
343static bool info_menu(void) 333bool info_menu(void)
344{ 334{
345 int m; 335 int m;
346 bool result; 336 bool result;
@@ -368,6 +358,7 @@ static bool info_menu(void)
368 return result; 358 return result;
369} 359}
370 360
361#if 0
371#ifdef HAVE_LCD_CHARCELLS 362#ifdef HAVE_LCD_CHARCELLS
372static bool do_shutdown(void) 363static bool do_shutdown(void)
373{ 364{
@@ -375,7 +366,6 @@ static bool do_shutdown(void)
375 return false; 366 return false;
376} 367}
377#endif 368#endif
378
379bool main_menu(void) 369bool main_menu(void)
380{ 370{
381 int m; 371 int m;
@@ -445,7 +435,7 @@ bool main_menu(void)
445 435
446 return result; 436 return result;
447} 437}
448 438#endif
449/* ----------------------------------------------------------------- 439/* -----------------------------------------------------------------
450 * vim: et sw=4 ts=8 sts=4 tw=78 440 * vim: et sw=4 ts=8 sts=4 tw=78
451 */ 441 */
diff --git a/apps/menu.c b/apps/menu.c
index 261286b8fa..9c5afbe94a 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -35,12 +35,14 @@
35#include "usb.h" 35#include "usb.h"
36#include "panic.h" 36#include "panic.h"
37#include "settings.h" 37#include "settings.h"
38#include "settings_list.h"
38#include "status.h" 39#include "status.h"
39#include "screens.h" 40#include "screens.h"
40#include "talk.h" 41#include "talk.h"
41#include "lang.h" 42#include "lang.h"
42#include "misc.h" 43#include "misc.h"
43#include "action.h" 44#include "action.h"
45#include "menus/exported_menus.h"
44 46
45#ifdef HAVE_LCD_BITMAP 47#ifdef HAVE_LCD_BITMAP
46#include "icons.h" 48#include "icons.h"
@@ -356,3 +358,337 @@ void put_cursorxy(int x, int y, bool on)
356#endif 358#endif
357 } 359 }
358} 360}
361
362/******************************************************************/
363/* New menu stuff here!!
364 ******************************************************************/
365
366
367/* used to allow for dynamic menus */
368#define MAX_MENU_SUBITEMS 64
369static int current_subitems[MAX_MENU_SUBITEMS];
370static int current_subitems_count = 0;
371
372void get_menu_callback(const struct menu_item_ex *m,
373 menu_callback_type menu_callback)
374{
375 if (m->flags&MENU_HAS_DESC)
376 menu_callback= m->callback_and_desc->menu_callback;
377 else menu_callback = m->menu_callback;
378}
379
380static int get_menu_selection(int selected_item, const struct menu_item_ex *menu)
381{
382 int type = (menu->flags&MENU_TYPE_MASK);
383 if (type == MT_MENU && (selected_item<current_subitems_count))
384 return current_subitems[selected_item];
385 return selected_item;
386}
387
388static char * get_menu_item_name(int selected_item,void * data, char *buffer)
389{
390 const struct menu_item_ex *menu = (const struct menu_item_ex *)data;
391 int type = (menu->flags&MENU_TYPE_MASK);
392 selected_item = get_menu_selection(selected_item, menu);
393
394 (void)buffer;
395 /* only MT_MENU or MT_RETURN_ID is allowed in here */
396 if (type == MT_RETURN_ID)
397 {
398 return (char*)menu->strings[selected_item];
399 }
400
401 menu = menu->submenus[selected_item];
402 type = (menu->flags&MENU_TYPE_MASK);
403 if (type == MT_SETTING)
404 {
405 const struct settings_list *v
406 = find_setting(menu->variable);
407 if (v)
408 return str(v->lang_id);
409 else return "Not Done yet!";
410 }
411 return P2STR(menu->callback_and_desc->desc);
412}
413
414static void init_menu_lists(const struct menu_item_ex *menu,
415 struct gui_synclist *lists, int selected, bool callback)
416{
417 int i, count = (menu->flags&MENU_COUNT_MASK)>>MENU_COUNT_SHIFT;
418 menu_callback_type menu_callback = NULL;
419 current_subitems_count = 0;
420 for (i=0; i<count; i++)
421 {
422 get_menu_callback(menu->submenus[i],menu_callback);
423 if (menu_callback)
424 {
425 if (menu_callback(ACTION_REQUEST_MENUITEM,menu->submenus[i])
426 != ACTION_EXIT_MENUITEM)
427 {
428 current_subitems[current_subitems_count] = i;
429 current_subitems_count++;
430 }
431 }
432 else
433 {
434 current_subitems[current_subitems_count] = i;
435 current_subitems_count++;
436 }
437 }
438
439 gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,1);
440 gui_synclist_set_title(lists, P2STR(menu->callback_and_desc->desc), NOICON);
441 gui_synclist_set_icon_callback(lists,NULL);
442 gui_synclist_set_nb_items(lists,current_subitems_count);
443 gui_synclist_limit_scroll(lists,true);
444 gui_synclist_select_item(lists, selected);
445
446 get_menu_callback(menu,menu_callback);
447 if (callback && menu_callback)
448 menu_callback(ACTION_ENTER_MENUITEM,menu);
449}
450
451static void talk_menu_item(const struct menu_item_ex *menu,
452 struct gui_synclist *lists)
453{
454 int id = -1;
455 if (global_settings.talk_menu)
456 {
457 int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
458 if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
459 {
460 if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING)
461 talk_setting(menu->submenus[sel]->variable);
462 else
463 {
464 id = P2ID(menu->submenus[sel]->callback_and_desc->desc);
465 if (id != -1)
466 talk_id(id,false);
467 }
468 }
469 }
470}
471#define MAX_OPTIONS 32
472int do_menu(const struct menu_item_ex *start_menu)
473{
474 int action;
475 int selected = 0;
476 struct gui_synclist lists;
477 const struct menu_item_ex *temp, *menu;
478 int ret = 0;
479
480 const struct menu_item_ex *menu_stack[MAX_MENUS];
481 int menu_stack_selected_item[MAX_MENUS];
482 int stack_top = 0;
483 bool in_stringlist;
484 menu_callback_type menu_callback = NULL;
485 if (start_menu == NULL)
486 menu = &main_menu_;
487 else menu = start_menu;
488
489 init_menu_lists(menu,&lists,selected,true);
490 in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID);
491
492 talk_menu_item(menu, &lists);
493
494 gui_synclist_draw(&lists);
495 gui_syncstatusbar_draw(&statusbars, true);
496 action_signalscreenchange();
497
498 while (ret == 0)
499 {
500 action = get_action(CONTEXT_MAINMENU,HZ);
501 /* HZ so the status bar redraws corectly */
502 if (action == ACTION_NONE)
503 {
504 gui_syncstatusbar_draw(&statusbars, true);
505 continue;
506 }
507
508 get_menu_callback(menu,menu_callback);
509 if (menu_callback)
510 {
511 action = menu_callback(action,menu);
512 }
513
514 if (gui_synclist_do_button(&lists,action,LIST_WRAP_UNLESS_HELD))
515 {
516 talk_menu_item(menu, &lists);
517 }
518 else if (action == ACTION_MENU_WPS)
519 {
520 ret = MENU_RETURN_TO_WPS;
521 }
522 else if ((action == ACTION_STD_CANCEL) ||
523 (action == ACTION_STD_MENU))
524 {
525 if (in_stringlist)
526 in_stringlist = false;
527 if (stack_top > 0)
528 {
529 get_menu_callback(menu,menu_callback);
530 if (menu_callback)
531 {
532 if (menu_callback(action,menu) ==
533 ACTION_EXIT_MENUITEM)
534 break;
535 }
536 stack_top--;
537 menu = menu_stack[stack_top];
538 init_menu_lists(menu, &lists,
539 menu_stack_selected_item[stack_top], false);
540 talk_menu_item(menu, &lists);
541 }
542 else
543 {
544 break;
545 }
546 }
547 else if (action == ACTION_STD_OK)
548 {
549 int type;
550 selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu);
551 temp = menu->submenus[selected];
552 if (in_stringlist)
553 type = (menu->flags&MENU_TYPE_MASK);
554 else type = (temp->flags&MENU_TYPE_MASK);
555 get_menu_callback(temp,menu_callback);
556 if (menu_callback)
557 {
558 action = menu_callback(ACTION_ENTER_MENUITEM,temp);
559 if (action == ACTION_EXIT_MENUITEM)
560 break;
561 }
562 switch (type)
563 {
564 case MT_MENU:
565 if (stack_top < MAX_MENUS)
566 {
567 menu_stack[stack_top] = menu;
568 menu_stack_selected_item[stack_top]
569 = gui_synclist_get_sel_pos(&lists);
570 stack_top++;
571 init_menu_lists(temp, &lists, 0, true);
572 menu = temp;
573 talk_menu_item(menu, &lists);
574 }
575 break;
576 case MT_FUNCTION_CALL:
577 action_signalscreenchange();
578 temp->function();
579 break;
580 case MT_FUNCTION_WITH_PARAM:
581 action_signalscreenchange();
582 temp->func_with_param->function(
583 temp->func_with_param->param);
584 break;
585 case MT_SETTING:
586 {
587 const struct settings_list *setting = find_setting(
588 temp->variable);
589 if (setting)
590 {
591 if ((setting->flags&F_BOOL_SETTING) == F_BOOL_SETTING)
592 {
593 bool temp_var, *var;
594 if (setting->flags&F_TEMPVAR)
595 {
596 temp_var = *(bool*)setting->setting;
597 var = &temp_var;
598 }
599 else
600 {
601 var = (bool*)setting->setting;
602 }
603 set_bool_options(str(setting->lang_id),var,
604 STR(setting->bool_setting->lang_yes),
605 STR(setting->bool_setting->lang_no),
606 setting->bool_setting->option_callback);
607 if (setting->flags&F_TEMPVAR)
608 *(bool*)setting->setting = temp_var;
609 }
610 else if (setting->flags&F_T_SOUND)
611 {
612 set_sound(str(setting->lang_id), setting->setting,
613 setting->sound_setting->setting);
614 }
615 else /* other setting, must be an INT type */
616 {
617 int temp_var, *var;
618 if (setting->flags&F_TEMPVAR)
619 {
620 temp_var = *(int*)setting->setting;
621 var = &temp_var;
622 }
623 else
624 {
625 var = (int*)setting->setting;
626 }
627 DEBUGF("%x\n",setting->flags);
628 if (setting->flags&F_INT_SETTING)
629 {DEBUGF("boo");
630 set_int(str(setting->lang_id),
631 str(setting->int_setting->unit),
632 setting->int_setting->unit,var,
633 setting->int_setting->option_callback,
634 setting->int_setting->step,
635 setting->int_setting->min,
636 setting->int_setting->max,
637 setting->int_setting->formatter);
638 }
639 else if (setting->flags&F_CHOICE_SETTING)
640 {
641 static struct opt_items options[MAX_OPTIONS];
642 int i,j, count = setting->choice_setting->count;
643 for (i=0, j=0; i<count && i<MAX_OPTIONS; i++)
644 {
645 options[j].string =
646 P2STR(setting->choice_setting->desc[i]);
647 options[j].voice_id =
648 P2ID(setting->choice_setting->desc[i]);
649 j++;
650 }
651 set_option(str(setting->lang_id), var, INT,
652 options,count,
653 setting->choice_setting->option_callback);
654 }
655 if (setting->flags&F_TEMPVAR)
656 *(int*)setting->setting = temp_var;
657 }
658 }
659 break;
660 }
661 case MT_RETURN_ID:
662 if (in_stringlist)
663 {
664 action_signalscreenchange();
665 return selected;
666 }
667 else if (stack_top < MAX_MENUS)
668 {
669 menu_stack[stack_top] = menu;
670 menu_stack_selected_item[stack_top] = selected;
671 stack_top++;
672 menu = temp;
673 init_menu_lists(menu,&lists,0,false);
674 in_stringlist = true;
675 }
676 break;
677 }
678 get_menu_callback(temp,menu_callback);
679 if (type != MT_MENU && menu_callback)
680 menu_callback(ACTION_EXIT_MENUITEM,temp);
681 }
682 else if(default_event_handler(action) == SYS_USB_CONNECTED)
683 ret = MENU_ATTACHED_USB;
684 gui_syncstatusbar_draw(&statusbars, true);
685 gui_synclist_draw(&lists);
686 }
687 action_signalscreenchange();
688 return ret;
689}
690
691int main_menu(void)
692{
693 return do_menu(NULL);
694}
diff --git a/apps/menu.h b/apps/menu.h
index f9a3d1ffd8..b0a1b4cb7f 100644
--- a/apps/menu.h
+++ b/apps/menu.h
@@ -22,101 +22,14 @@
22 22
23#include <stdbool.h> 23#include <stdbool.h>
24 24
25/* button definitions */
26#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
27 (CONFIG_KEYPAD == IRIVER_H300_PAD)
28#define MENU_EXIT BUTTON_LEFT
29#define MENU_EXIT2 BUTTON_OFF
30#define MENU_EXIT_MENU BUTTON_MODE
31#define MENU_ENTER BUTTON_RIGHT
32#define MENU_ENTER2 BUTTON_SELECT
33
34#define MENU_RC_EXIT BUTTON_RC_STOP
35#define MENU_RC_EXIT_MENU BUTTON_RC_MODE
36#define MENU_RC_ENTER BUTTON_RC_ON
37#define MENU_RC_ENTER2 BUTTON_RC_MENU
38
39
40#elif CONFIG_KEYPAD == RECORDER_PAD
41
42#define MENU_EXIT BUTTON_LEFT
43#define MENU_EXIT2 BUTTON_OFF
44#define MENU_EXIT_MENU BUTTON_F1
45#define MENU_ENTER BUTTON_RIGHT
46#define MENU_ENTER2 BUTTON_PLAY
47
48#define MENU_RC_EXIT BUTTON_RC_STOP
49#define MENU_RC_ENTER BUTTON_RC_PLAY
50
51#elif CONFIG_KEYPAD == PLAYER_PAD
52#define MENU_EXIT BUTTON_STOP
53#define MENU_EXIT_MENU BUTTON_MENU
54#define MENU_ENTER BUTTON_PLAY
55
56#define MENU_RC_EXIT BUTTON_RC_STOP
57#define MENU_RC_ENTER BUTTON_RC_PLAY
58
59#elif CONFIG_KEYPAD == ONDIO_PAD
60#define MENU_EXIT BUTTON_LEFT
61#define MENU_EXIT_MENU BUTTON_MENU
62#define MENU_ENTER BUTTON_RIGHT
63
64#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
65
66/* TODO: Check menu button assignments */
67
68#define MENU_NEXT BUTTON_DOWN
69#define MENU_PREV BUTTON_UP
70#define MENU_EXIT BUTTON_LEFT
71#define MENU_EXIT_MENU BUTTON_MENU
72#define MENU_ENTER BUTTON_RIGHT
73#define MENU_ENTER2 BUTTON_SELECT
74
75#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
76
77#define MENU_NEXT BUTTON_DOWN
78#define MENU_PREV BUTTON_UP
79#define MENU_EXIT BUTTON_LEFT
80#define MENU_EXIT_MENU BUTTON_PLAY
81#define MENU_ENTER BUTTON_RIGHT
82
83#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
84
85#define MENU_NEXT BUTTON_DOWN
86#define MENU_PREV BUTTON_UP
87#define MENU_EXIT BUTTON_LEFT
88#define MENU_EXIT_MENU BUTTON_REC
89#define MENU_ENTER BUTTON_RIGHT
90#define MENU_ENTER2 BUTTON_SELECT
91
92#elif CONFIG_KEYPAD == GIGABEAT_PAD
93
94#define MENU_EXIT BUTTON_LEFT
95#define MENU_EXIT2 BUTTON_A
96#define MENU_EXIT_MENU BUTTON_MENU
97#define MENU_ENTER BUTTON_RIGHT
98#define MENU_ENTER2 BUTTON_SELECT
99#define MENU_NEXT BUTTON_DOWN
100#define MENU_PREV BUTTON_UP
101
102#elif CONFIG_KEYPAD == IRIVER_H10_PAD
103
104#define MENU_NEXT BUTTON_SCROLL_DOWN
105#define MENU_PREV BUTTON_SCROLL_UP
106#define MENU_EXIT BUTTON_LEFT
107#define MENU_EXIT_MENU BUTTON_REW
108#define MENU_ENTER BUTTON_RIGHT
109#define MENU_ENTER2 BUTTON_FF
110
111#endif
112
113struct menu_item { 25struct menu_item {
114 unsigned char *desc; /* string or ID */ 26 unsigned char *desc; /* string or ID */
115 bool (*function) (void); /* return true if USB was connected */ 27 bool (*function) (void); /* return true if USB was connected */
116}; 28};
117 29
118int menu_init(const struct menu_item* mitems, int count, int (*callback)(int, int), 30int menu_init(const struct menu_item* mitems, int count,
119 const char *button1, const char *button2, const char *button3); 31 int (*callback)(int, int),
32 const char *button1, const char *button2, const char *button3);
120void menu_exit(int menu); 33void menu_exit(int menu);
121 34
122void put_cursorxy(int x, int y, bool on); 35void put_cursorxy(int x, int y, bool on);
@@ -125,6 +38,8 @@ void put_cursorxy(int x, int y, bool on);
125int menu_show(int m); 38int menu_show(int m);
126#define MENU_ATTACHED_USB -1 39#define MENU_ATTACHED_USB -1
127#define MENU_SELECTED_EXIT -2 40#define MENU_SELECTED_EXIT -2
41#define MENU_EXIT_ALL -3
42#define MENU_RETURN_TO_WPS -4
128 43
129bool menu_run(int menu); 44bool menu_run(int menu);
130int menu_cursor(int menu); 45int menu_cursor(int menu);
@@ -138,4 +53,87 @@ void menu_insert(int menu, int position, char *desc, bool (*function) (void));
138void menu_set_cursor(int menu, int position); 53void menu_set_cursor(int menu, int position);
139void menu_talk_selected(int m); 54void menu_talk_selected(int m);
140 55
56
57enum menu_item_type {
58 MT_MENU = 0,
59 MT_SETTING,
60 MT_FUNCTION_CALL, /* used when the standard code wont work */
61 MT_FUNCTION_WITH_PARAM,
62 MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
63};
64
65typedef int (*menu_function)(void);
66struct menu_func_with_param {
67 int (*function)(void* param);
68 void *param;
69};
70
71#define MENU_TYPE_MASK 0xF /* MT_* type */
72#define MENU_HAS_DESC 0x10
73#define MENU_COUNT_MASK (~(MENU_TYPE_MASK|MENU_HAS_DESC)) /* unless we need more flags*/
74#define MENU_COUNT_SHIFT 5
75
76struct menu_item_ex {
77 int flags; /* above defines */
78 union {
79 const struct menu_item_ex **submenus; /* used with MT_MENU */
80 void *variable; /* used with MT_SETTING,
81 must be in the settings_list.c list */
82 int (*function)(void); /* used with MT_FUNCTION_CALL */
83 const struct menu_func_with_param
84 *func_with_param; /* MT_FUNCTION_WITH_PARAM */
85 const char **strings; /* used with MT_RETURN_ID */
86 };
87 union {
88 int (*menu_callback)(int action, const struct menu_item_ex *this_item);
89 const struct menu_callback_with_desc {
90 int (*menu_callback)(int action,
91 const struct menu_item_ex *this_item);
92 unsigned char *desc; /* string or ID */
93 } *callback_and_desc;
94 };
95};
96
97typedef int (*menu_callback_type)(int action,
98 const struct menu_item_ex *this_item);
99int do_menu(const struct menu_item_ex *menu);
100
101#define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT)
102
103#define MENUITEM_SETTING(name,var,callback) \
104 static const struct menu_item_ex name = \
105 {MT_SETTING, {.variable = (void*)var},{callback}};
106
107#define MAKE_MENU( name, str, cb, ... ) \
108 static const struct menu_item_ex *name##_[] = {__VA_ARGS__}; \
109 static const struct menu_callback_with_desc name##__ = {cb,str}; \
110 const struct menu_item_ex name = \
111 {MT_MENU|MENU_HAS_DESC| \
112 MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \
113 { (void*)name##_},{.callback_and_desc = & name##__}};
114
115#define MENUITEM_STRINGLIST(name, str, callback, ... ) \
116 static const char *name##_[] = {__VA_ARGS__}; \
117 static const struct menu_callback_with_desc name##__ = {cb,str}; \
118 static const struct menu_item_ex name = \
119 {MT_RETURN_ID|MENU_HAS_DESC| \
120 MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \
121 { .submenus = name##_},{.callback_and_desc = & name##__}};
122/* This one should be static'ed also,
123 but cannot be done untill sound and playlist menus are done */
124#define MENUITEM_FUNCTION(name, str, func, cb) \
125 static const struct menu_callback_with_desc name##_ = {cb,str}; \
126 const struct menu_item_ex name = \
127 { MT_FUNCTION_CALL|MENU_HAS_DESC, { .function = func}, \
128 {.callback_and_desc = & name##_}};
129
130#define MENUITEM_FUNCTION_WPARAM(name, str, func, param, callback) \
131 static const struct menu_callback_with_desc name##_ = {callback,str}; \
132 static const struct menu_func_with_param name##__ = {func, param}; \
133 static const struct menu_item_ex name = \
134 { MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC, \
135 { .func_with_param = &name##__}, \
136 {.callback_and_desc = & name##_}};
137
138
141#endif /* End __MENU_H__ */ 139#endif /* End __MENU_H__ */
diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c
new file mode 100644
index 0000000000..30d321dc59
--- /dev/null
+++ b/apps/menus/display_menu.c
@@ -0,0 +1,32 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "settings_menu.h"
30
31bool display_settings_menu(void); /* from ../settings_menu.c */
32MENUITEM_FUNCTION(display_menu,ID2P(LANG_DISPLAY),(menu_function)display_settings_menu,NULL);
diff --git a/apps/menus/exported_menus.h b/apps/menus/exported_menus.h
new file mode 100644
index 0000000000..3d6a11a16e
--- /dev/null
+++ b/apps/menus/exported_menus.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2006 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#ifndef _EXPORTED_MENUS_H
20#define _EXPORTED_MENUS_H
21
22#include "menu.h"
23/* not needed for plugins */
24#ifndef PLUGIN
25
26extern const struct menu_item_ex
27 main_menu_, /* main_menu.c */
28 display_menu, /* display_menu.c */
29// playback_settings, /* playback_menu.c */
30#ifdef HAVE_RECORDING
31 recording_settings_menu, /* recording_menu.c */
32#endif
33 sound_settings, /* sound_menu.c */
34 settings_menu_item, /* settings_menu.c */
35 playlist_menu_item; /* playlist_menu.c */
36
37
38
39#endif /* ! PLUGIN */
40#endif /*_EXPORTED_MENUS_H */
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
new file mode 100644
index 0000000000..e830f4bbc7
--- /dev/null
+++ b/apps/menus/main_menu.c
@@ -0,0 +1,125 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "powermgmt.h"
29#include "menu.h"
30#include "settings_menu.h"
31#include "exported_menus.h"
32#include "tree.h"
33#ifdef CONFIG_TUNER
34#include "radio.h"
35#endif
36#ifdef HAVE_RECORDING
37#include "recording.h"
38#endif
39#include "bookmark.h"
40
41/* lazy coders can use this function if the needed callback
42 is just to say if the item is shown or not */
43int dynamicitem_callback(int action,const struct menu_item_ex *this_item);
44
45/***********************************/
46/* MAIN MENU */
47
48struct browse_folder_info {
49 const char* dir;
50 int show_options;
51};
52static struct browse_folder_info theme = {THEME_DIR, SHOW_CFG};
53static struct browse_folder_info rocks = {PLUGIN_DIR, SHOW_PLUGINS};
54static int browse_folder(void *param)
55{
56 const struct browse_folder_info *info =
57 (const struct browse_folder_info*)param;
58 return rockbox_browse(info->dir, info->show_options);
59}
60MENUITEM_FUNCTION_WPARAM(browse_themes, ID2P(LANG_CUSTOM_THEME),
61 browse_folder, (void*)&theme, NULL);
62MENUITEM_FUNCTION_WPARAM(browse_plugins, ID2P(LANG_PLUGINS),
63 browse_folder, (void*)&rocks, NULL);
64
65#ifdef CONFIG_TUNER
66MENUITEM_FUNCTION(load_radio_screen, ID2P(LANG_FM_RADIO),
67 (menu_function)radio_screen, dynamicitem_callback);
68#endif
69
70#include "settings_menu.h"
71MENUITEM_FUNCTION(manage_settings_menu_item, ID2P(LANG_MANAGE_MENU),
72 (menu_function)manage_settings_menu, NULL);
73bool info_menu(void); /* from apps/main_menu.c TEMP*/
74MENUITEM_FUNCTION(info_menu_item, ID2P(LANG_INFO),
75 (menu_function)info_menu, NULL);
76MENUITEM_FUNCTION(mrb_bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
77 (menu_function)bookmark_mrb_load, NULL);
78
79#ifdef HAVE_LCD_CHARCELLS
80static int do_shutdown(void)
81{
82 sys_poweroff();
83 return 0;
84}
85MENUITEM_FUNCTION(do_shutdown_item, ID2P(LANG_SHUTDOWN), do_shutdown, NULL);
86#endif
87
88/* NOTE: This title will be translatable once we decide what to call this menu
89 when the root menu comes in... hopefully in the next few days */
90MAKE_MENU(main_menu_, "ROCKbox Main Menu", NULL,
91 &mrb_bookmarks, &sound_settings,
92 &settings_menu_item, &manage_settings_menu_item, &browse_themes,
93#ifdef CONFIG_TUNER
94 &load_radio_screen,
95#endif
96#ifdef HAVE_RECORDING
97 &recording_settings_menu,
98#endif
99 &playlist_menu_item, &browse_plugins, &info_menu_item
100#ifdef HAVE_LCD_CHARCELLS
101 ,&do_shutdown_item
102#endif
103 );
104/* MAIN MENU */
105/***********************************/
106
107/* lazy coders can use this function if the needed
108 callback is just to say if the item is shown or not */
109int dynamicitem_callback(int action,const struct menu_item_ex *this_item)
110{
111 if (action != ACTION_ENTER_MENUITEM)
112 return action;
113
114#ifdef CONFIG_TUNER
115 if (this_item == &load_radio_screen)
116 {
117 if (radio_hardware_present() == 0)
118 return ACTION_EXIT_MENUITEM;
119 }
120#else
121 (void)this_item;
122#endif
123
124 return action;
125}
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
new file mode 100644
index 0000000000..b38870e540
--- /dev/null
+++ b/apps/menus/playlist_menu.c
@@ -0,0 +1,32 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "playlist_menu.h"
30
31MENUITEM_FUNCTION(playlist_menu_item, ID2P(LANG_PLAYLIST_MENU), (menu_function)playlist_menu, NULL);
32
diff --git a/apps/menus/recording_menu.c b/apps/menus/recording_menu.c
new file mode 100644
index 0000000000..d1aed69dea
--- /dev/null
+++ b/apps/menus/recording_menu.c
@@ -0,0 +1,41 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "recording.h"
30
31#ifdef HAVE_RECORDING
32MENUITEM_FUNCTION(rec_menu_recording_screen_item, ID2P(LANG_RECORDING_MENU),
33 (menu_function)recording_screen, NULL);
34/* TEMP */
35bool recording_menu(bool no_source); /* from apps/sound_menu.h */
36MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_MENU),
37 (int (*)(void*))recording_menu,0, NULL);
38
39MAKE_MENU(recording_settings_menu,ID2P(LANG_RECORDING),0,
40 &rec_menu_recording_screen_item, &recording_settings);
41#endif
diff --git a/apps/menus/recording_settings_menu.c b/apps/menus/recording_settings_menu.c
new file mode 100644
index 0000000000..1bc38ddbcd
--- /dev/null
+++ b/apps/menus/recording_settings_menu.c
@@ -0,0 +1,33 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "settings_menu.h"
30#include "playback_menu.h"
31
32bool display_settings_menu(void); /* from ../settings_menu.c */
33MENUITEM_FUNCTION(display_menu,ID2P(LANG_DISPLAY),display_settings_menu,NULL);
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c
new file mode 100644
index 0000000000..3ea35320dd
--- /dev/null
+++ b/apps/menus/settings_menu.c
@@ -0,0 +1,33 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "sound_menu.h"
30
31#include "settings_menu.h"
32MENUITEM_FUNCTION(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS),
33 (menu_function)settings_menu, NULL);
diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c
new file mode 100644
index 0000000000..6d656da14d
--- /dev/null
+++ b/apps/menus/sound_menu.c
@@ -0,0 +1,32 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "settings.h"
28#include "menu.h"
29#include "sound_menu.h"
30
31MENUITEM_FUNCTION(sound_settings, ID2P(LANG_SOUND_SETTINGS), (menu_function)sound_menu, NULL);
32
diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h
index a67337b9b6..e78af50671 100644
--- a/apps/recorder/recording.h
+++ b/apps/recorder/recording.h
@@ -18,6 +18,7 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifndef RECORDING_H 19#ifndef RECORDING_H
20#define RECORDING_H 20#define RECORDING_H
21#include "audio.h"
21 22
22bool recording_screen(bool no_source); 23bool recording_screen(bool no_source);
23char *rec_create_filename(char *buf); 24char *rec_create_filename(char *buf);
diff --git a/apps/settings.c b/apps/settings.c
index 2cdab771db..4d4a96c639 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -19,6 +19,7 @@
19 ****************************************************************************/ 19 ****************************************************************************/
20#include <stdio.h> 20#include <stdio.h>
21#include <stddef.h> 21#include <stddef.h>
22#include <stdlib.h>
22#include <limits.h> 23#include <limits.h>
23#include "inttypes.h" 24#include "inttypes.h"
24#include "config.h" 25#include "config.h"
@@ -922,6 +923,78 @@ void settings_reset(void) {
922} 923}
923 924
924/** Changing setting values **/ 925/** Changing setting values **/
926const struct settings_list* find_setting(void* variable)
927{
928 int i;
929 for(i=0;i<nb_settings;i++)
930 {
931 if (settings[i].setting == variable)
932 return &settings[i];
933 }
934 return NULL;
935}
936
937void talk_setting(void *global_settings_variable)
938{
939 const struct settings_list *setting;
940 if (global_settings.talk_menu == 0)
941 return;
942 setting = find_setting(global_settings_variable);
943 if (setting == NULL)
944 return;
945 if (setting->lang_id)
946 talk_id(setting->lang_id,false);
947}
948static int selected_setting; /* Used by the callback */
949static void dec_sound_formatter(char *buffer, int buffer_size,
950 int val, const char *unit)
951{
952 val = sound_val2phys(selected_setting, val);
953 char sign = ' ';
954 if(val < 0)
955 {
956 sign = '-';
957 val = abs(val);
958 }
959 int integer = val / 10;
960 int dec = val % 10;
961 snprintf(buffer, buffer_size, "%c%d.%d %s", sign, integer, dec, unit);
962}
963bool set_sound(const unsigned char * string,
964 int* variable,
965 int setting)
966{
967 int talkunit = UNIT_INT;
968 const char* unit = sound_unit(setting);
969 int numdec = sound_numdecimals(setting);
970 int steps = sound_steps(setting);
971 int min = sound_min(setting);
972 int max = sound_max(setting);
973 sound_set_type* sound_callback = sound_get_fn(setting);
974 if (*unit == 'd') /* crude reconstruction */
975 talkunit = UNIT_DB;
976 else if (*unit == '%')
977 talkunit = UNIT_PERCENT;
978 else if (*unit == 'H')
979 talkunit = UNIT_HERTZ;
980 if(!numdec)
981#if CONFIG_CODEC == SWCODEC
982 /* We need to hijack this one and send it off to apps/dsp.c instead of
983 firmware/sound.c */
984 if (setting == SOUND_STEREO_WIDTH)
985 return set_int(string, unit, talkunit, variable, &stereo_width_set,
986 steps, min, max, NULL );
987 else
988#endif
989 return set_int(string, unit, talkunit, variable, sound_callback,
990 steps, min, max, NULL );
991 else
992 {/* Decimal number */
993 selected_setting=setting;
994 return set_int(string, unit, talkunit, variable, sound_callback,
995 steps, min, max, &dec_sound_formatter );
996 }
997}
925 998
926bool set_bool(const char* string, bool* variable ) 999bool set_bool(const char* string, bool* variable )
927{ 1000{
diff --git a/apps/settings.h b/apps/settings.h
index 379084b885..8244163e2e 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -224,6 +224,10 @@ struct opt_items {
224 unsigned const char* string; 224 unsigned const char* string;
225 long voice_id; 225 long voice_id;
226}; 226};
227const struct settings_list* find_setting(void* variable);
228void talk_setting(void *global_settings_variable);
229bool set_sound(const unsigned char * string,
230 int* variable, int setting);
227bool set_bool_options(const char* string, bool* variable, 231bool set_bool_options(const char* string, bool* variable,
228 const char* yes_str, int yes_voice, 232 const char* yes_str, int yes_voice,
229 const char* no_str, int no_voice, 233 const char* no_str, int no_voice,
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 8641cd83b9..5f784d4998 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -21,10 +21,12 @@
21#include <stdbool.h> 21#include <stdbool.h>
22 22
23#include "lang.h" 23#include "lang.h"
24#include "talk.h"
24#include "lcd.h" 25#include "lcd.h"
25#include "settings.h" 26#include "settings.h"
26#include "settings_list.h" 27#include "settings_list.h"
27#include "sound.h" 28#include "sound.h"
29#include "dsp.h"
28 30
29/* some sets of values which are used more than once, to save memory */ 31/* some sets of values which are used more than once, to save memory */
30static const char off_on[] = "off,on"; 32static const char off_on[] = "off,on";
@@ -92,24 +94,39 @@ static const char backlight_times_conf [] =
92#define NODEFAULT INT(0) 94#define NODEFAULT INT(0)
93 95
94#define SOUND_SETTING(flags,var,lang_id,setting) \ 96#define SOUND_SETTING(flags,var,lang_id,setting) \
95 {flags|F_T_INT|F_T_SOUND, GS(var),lang_id, NODEFAULT,#var,NULL,\ 97 {flags|F_T_INT|F_T_SOUND, GS(var),lang_id, NODEFAULT,#var,NULL,\
96 {.sound_setting=(struct sound_setting[]){{setting}}} } 98 {.sound_setting=(struct sound_setting[]){{setting}}} }
97 99
98#define BOOL_SETTING(flags,var,lang_id,default,name,cfgvals,yes,no,opt_cb) \ 100#define BOOL_SETTING(flags,var,lang_id,default,name,cfgvals,yes,no,opt_cb) \
99 {flags|F_T_BOOL, GS(var),lang_id, BOOL(default),name,cfgvals, \ 101 {flags|F_BOOL_SETTING, GS(var),lang_id, BOOL(default),name,cfgvals,\
100 {.bool_setting=(struct bool_setting[]){{opt_cb,yes,no}}} } 102 {.bool_setting=(struct bool_setting[]){{opt_cb,yes,no}}} }
101 103
102#define OFFON_SETTING(flags,var,lang_id,default,name,cb) \ 104#define OFFON_SETTING(flags,var,lang_id,default,name,cb) \
103 {flags|F_T_BOOL, GS(var),lang_id, BOOL(default),name,off_on, \ 105 {flags|F_BOOL_SETTING, GS(var),lang_id, BOOL(default),name,off_on, \
104 {.bool_setting=(struct bool_setting[]) \ 106 {.bool_setting=(struct bool_setting[]) \
105 {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} } 107 {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} }
106 108
107#define SYSTEM_SETTING(flags,var,default) \ 109#define SYSTEM_SETTING(flags,var,default) \
108 {flags|F_T_INT, &global_status.var,-1, INT(default), NULL, NULL, UNUSED} 110 {flags|F_T_INT, &global_status.var,-1, INT(default), \
111 NULL, NULL, UNUSED}
109 112
110#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \ 113#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \
111 {flags|F_T_UCHARPTR, GS(var),-1, CHARPTR(default),name,NULL,\ 114 {flags|F_T_UCHARPTR, GS(var),-1, CHARPTR(default),name,NULL,\
112 {.filename_setting=(struct filename_setting[]){{prefix,suffix,len}}} } 115 {.filename_setting= \
116 (struct filename_setting[]){{prefix,suffix,len}}} }
117
118#define CHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \
119 {flags|F_CHOICE_SETTING|F_T_INT, GS(var), lang_id, \
120 INT(default), name, cfg_vals, \
121 {.choice_setting = (struct choice_setting[]){ \
122 {cb,count,(unsigned char*[]){__VA_ARGS__}}}}}
123
124#define INT_SETTING(flags, var, lang_id, default, name, cfg_vals, \
125 unit, min, max, step, formatter, cb) \
126 {flags|F_INT_SETTING|F_T_INT, GS(var), lang_id, INT(default), \
127 name, cfg_vals, {.int_setting = (struct int_setting[]){ \
128 {cb, unit, min, max, step, formatter}}}}
129
113const struct settings_list settings[] = { 130const struct settings_list settings[] = {
114 /* sound settings */ 131 /* sound settings */
115 SOUND_SETTING(0,volume, LANG_VOLUME, SOUND_VOLUME), 132 SOUND_SETTING(0,volume, LANG_VOLUME, SOUND_VOLUME),
@@ -122,10 +139,17 @@ const struct settings_list settings[] = {
122 "off,20ms,2,4,8", UNUSED }, 139 "off,20ms,2,4,8", UNUSED },
123 OFFON_SETTING(0,superbass,LANG_SUPERBASS,false,"superbass",NULL), 140 OFFON_SETTING(0,superbass,LANG_SUPERBASS,false,"superbass",NULL),
124#endif 141#endif
125 { F_T_INT, GS(channel_config), LANG_CHANNEL, INT(0), "channels", 142 CHOICE_SETTING(0,channel_config,LANG_CHANNEL,0,"channels",
126 "stereo,mono,custom,mono left,mono right,karaoke", UNUSED }, 143 "stereo,mono,custom,mono left,mono right,karaoke",
127 { F_T_INT, GS(stereo_width),LANG_STEREO_WIDTH, 144#if CONFIG_CODEC == SWCODEC
128 INT(100), "stereo width", NULL, UNUSED }, 145 channels_set,
146#else
147 sound_set_channels,
148#endif
149 6, ID2P(LANG_CHANNEL_STEREO), ID2P(LANG_CHANNEL_MONO),
150 ID2P(LANG_CHANNEL_CUSTOM), ID2P(LANG_CHANNEL_LEFT),
151 ID2P(LANG_CHANNEL_RIGHT), ID2P(LANG_CHANNEL_KARAOKE)),
152 SOUND_SETTING(0,stereo_width, LANG_STEREO_WIDTH, SOUND_STEREO_WIDTH),
129 /* playback */ 153 /* playback */
130 OFFON_SETTING(0, resume, LANG_RESUME, false, "resume", NULL), 154 OFFON_SETTING(0, resume, LANG_RESUME, false, "resume", NULL),
131 OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL), 155 OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL),
@@ -174,8 +198,8 @@ const struct settings_list settings[] = {
174 SYSTEM_SETTING(NVRAM(4),runtime,0), 198 SYSTEM_SETTING(NVRAM(4),runtime,0),
175 SYSTEM_SETTING(NVRAM(4),topruntime,0), 199 SYSTEM_SETTING(NVRAM(4),topruntime,0),
176#if MEM > 1 200#if MEM > 1
177 {F_T_INT,GS(max_files_in_playlist),LANG_MAX_FILES_IN_PLAYLIST, 201 INT_SETTING(0,max_files_in_playlist,LANG_MAX_FILES_IN_PLAYLIST,10000,
178 INT(10000),"max files in playlist",NULL,UNUSED}, 202 "max files in playlist", NULL, UNIT_INT,1000,20000,1000,NULL,NULL),
179 {F_T_INT,GS(max_files_in_dir),LANG_MAX_FILES_IN_DIR, 203 {F_T_INT,GS(max_files_in_dir),LANG_MAX_FILES_IN_DIR,
180 INT(400),"max files in dir",NULL,UNUSED}, 204 INT(400),"max files in dir",NULL,UNUSED},
181#else 205#else
diff --git a/apps/settings_list.h b/apps/settings_list.h
index 195703bfe3..663d9db228 100644
--- a/apps/settings_list.h
+++ b/apps/settings_list.h
@@ -53,7 +53,7 @@ struct bool_setting {
53 int lang_yes; 53 int lang_yes;
54 int lang_no; 54 int lang_no;
55}; 55};
56#define F_BOOL_SETTING F_T_BOOL|0x10 56#define F_BOOL_SETTING (F_T_BOOL|0x10)
57#define F_RGB 0x20 57#define F_RGB 0x20
58 58
59struct filename_setting { 59struct filename_setting {
@@ -64,29 +64,42 @@ struct filename_setting {
64#define F_FILENAME 0x40 64#define F_FILENAME 0x40
65 65
66struct int_setting { 66struct int_setting {
67 void (*option_callback)(int); 67 void (*option_callback)(int);
68 int min; 68 int unit;
69 int max; 69 int min;
70 int step; 70 int max;
71 int step;
72 void (*formatter)(char*, int, int, const char*);
71}; 73};
74#define F_INT_SETTING 0x80
75
76struct choice_setting {
77 void (*option_callback)(int);
78 int count;
79 unsigned char **desc;
80};
81#define F_CHOICE_SETTING 0x100
82
72/* these use the _isfunc_type type for the function */ 83/* these use the _isfunc_type type for the function */
73/* typedef int (*_isfunc_type)(void); */ 84/* typedef int (*_isfunc_type)(void); */
74#define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */ 85#define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */
75#define F_MAX_ISFUNC 0x200000 /* max(above) is function pointer to above type */ 86#define F_MAX_ISFUNC 0x200000 /* max(above) is function pointer to above type */
76#define F_DEF_ISFUNC 0x400000 /* default_val is function pointer to above type */ 87#define F_DEF_ISFUNC 0x400000 /* default_val is function pointer to above type */
77 88
78#define F_NVRAM_BYTES_MASK 0xE00 /*0-4 bytes can be stored */ 89#define F_THEMESETTING 0x800000
79#define F_NVRAM_MASK_SHIFT 9 90
91#define F_NVRAM_BYTES_MASK 0xE000 /*0-4 bytes can be stored */
92#define F_NVRAM_MASK_SHIFT 13
80#define NVRAM_CONFIG_VERSION 2 93#define NVRAM_CONFIG_VERSION 2
81/* Above define should be bumped if 94/* Above define should be bumped if
82- a new NVRAM setting is added between 2 other NVRAM settings 95- a new NVRAM setting is added between 2 other NVRAM settings
83- number of bytes for a NVRAM setting is changed 96- number of bytes for a NVRAM setting is changed
84- a NVRAM setting is removed 97- a NVRAM setting is removed
85*/ 98*/
86#define F_THEMESETTING 0x800000 99#define F_TEMPVAR 0x200 /* used if the setting should be set using a temp var */
87 100
88struct settings_list { 101struct settings_list {
89 uint32_t flags; /* ____ ____ TFFF ____ ____ NNN_ IFRB STTT */ 102 uint32_t flags; /* ____ ____ TFFF ____ NNN_ __TC IFRB STTT */
90 void *setting; 103 void *setting;
91 int lang_id; /* -1 for none */ 104 int lang_id; /* -1 for none */
92 union storage_type default_val; 105 union storage_type default_val;
@@ -98,6 +111,8 @@ struct settings_list {
98 struct sound_setting *sound_setting; /* use F_T_SOUND for this */ 111 struct sound_setting *sound_setting; /* use F_T_SOUND for this */
99 struct bool_setting *bool_setting; /* F_BOOL_SETTING */ 112 struct bool_setting *bool_setting; /* F_BOOL_SETTING */
100 struct filename_setting *filename_setting; /* use F_FILENAME */ 113 struct filename_setting *filename_setting; /* use F_FILENAME */
114 struct int_setting *int_setting; /* use F_INT_SETTING */
115 struct choice_setting *choice_setting; /* F_CHOICE_SETTING */
101 }; 116 };
102}; 117};
103 118
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 8e6fbd02d7..054dd145a9 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -1767,7 +1767,7 @@ static bool unplug_menu(void)
1767} 1767}
1768#endif 1768#endif
1769 1769
1770static bool playback_settings_menu(void) 1770bool playback_settings_menu(void)
1771{ 1771{
1772 int m; 1772 int m;
1773 bool result; 1773 bool result;
@@ -2061,7 +2061,7 @@ static bool bars_settings_menu(void)
2061#endif 2061#endif
2062 2062
2063 2063
2064static bool display_settings_menu(void) 2064bool display_settings_menu(void)
2065{ 2065{
2066 int m; 2066 int m;
2067 bool result; 2067 bool result;
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 19dc57b1a7..f7ddc430cc 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -61,57 +61,6 @@
61#endif 61#endif
62#include "action.h" 62#include "action.h"
63 63
64static int selected_setting; /* Used by the callback */
65static void dec_sound_formatter(char *buffer, int buffer_size, int val, const char *unit)
66{
67 val = sound_val2phys(selected_setting, val);
68 char sign = ' ';
69 if(val < 0)
70 {
71 sign = '-';
72 val = abs(val);
73 }
74 int integer = val / 10;
75 int dec = val % 10;
76 snprintf(buffer, buffer_size, "%c%d.%d %s", sign, integer, dec, unit);
77}
78
79bool set_sound(const unsigned char * string,
80 int* variable,
81 int setting)
82{
83 int talkunit = UNIT_INT;
84 const char* unit = sound_unit(setting);
85 int numdec = sound_numdecimals(setting);
86 int steps = sound_steps(setting);
87 int min = sound_min(setting);
88 int max = sound_max(setting);
89 sound_set_type* sound_callback = sound_get_fn(setting);
90 if (*unit == 'd') /* crude reconstruction */
91 talkunit = UNIT_DB;
92 else if (*unit == '%')
93 talkunit = UNIT_PERCENT;
94 else if (*unit == 'H')
95 talkunit = UNIT_HERTZ;
96 if(!numdec)
97#if CONFIG_CODEC == SWCODEC
98 /* We need to hijack this one and send it off to apps/dsp.c instead of
99 firmware/sound.c */
100 if (setting == SOUND_STEREO_WIDTH)
101 return set_int(string, unit, talkunit, variable, &stereo_width_set,
102 steps, min, max, NULL );
103 else
104#endif
105 return set_int(string, unit, talkunit, variable, sound_callback,
106 steps, min, max, NULL );
107 else
108 {/* Decimal number */
109 selected_setting=setting;
110 return set_int(string, unit, talkunit, variable, sound_callback,
111 steps, min, max, &dec_sound_formatter );
112 }
113}
114
115static bool volume(void) 64static bool volume(void)
116{ 65{
117 return set_sound(str(LANG_VOLUME), &global_settings.volume, SOUND_VOLUME); 66 return set_sound(str(LANG_VOLUME), &global_settings.volume, SOUND_VOLUME);
diff --git a/apps/sound_menu.h b/apps/sound_menu.h
index 4e85b9c03c..4d295b0a70 100644
--- a/apps/sound_menu.h
+++ b/apps/sound_menu.h
@@ -24,6 +24,5 @@
24bool sound_menu(void); 24bool sound_menu(void);
25bool recording_menu(bool no_source); 25bool recording_menu(bool no_source);
26bool rectrigger(void); 26bool rectrigger(void);
27bool set_sound(const unsigned char * string, int* variable, int setting);
28 27
29#endif 28#endif