diff options
-rw-r--r-- | apps/menu.c | 132 |
1 files changed, 68 insertions, 64 deletions
diff --git a/apps/menu.c b/apps/menu.c index 4991b05383..830bc67a11 100644 --- a/apps/menu.c +++ b/apps/menu.c | |||
@@ -67,6 +67,12 @@ static int current_subitems[MAX_MENU_SUBITEMS]; | |||
67 | static int current_subitems_count = 0; | 67 | static int current_subitems_count = 0; |
68 | static int talk_menu_item(int selected_item, void *data); | 68 | static int talk_menu_item(int selected_item, void *data); |
69 | 69 | ||
70 | struct menu_data_t | ||
71 | { | ||
72 | const struct menu_item_ex *menu; | ||
73 | int selected; | ||
74 | }; | ||
75 | |||
70 | static void get_menu_callback(const struct menu_item_ex *m, | 76 | static void get_menu_callback(const struct menu_item_ex *m, |
71 | menu_callback_type *menu_callback) | 77 | menu_callback_type *menu_callback) |
72 | { | 78 | { |
@@ -76,6 +82,19 @@ static void get_menu_callback(const struct menu_item_ex *m, | |||
76 | *menu_callback = m->menu_callback; | 82 | *menu_callback = m->menu_callback; |
77 | } | 83 | } |
78 | 84 | ||
85 | static bool query_audio_status(int *old_audio_status) | ||
86 | { | ||
87 | bool redraw_list = false; | ||
88 | /* query audio status to see if it changed */ | ||
89 | int new_audio_status = audio_status(); | ||
90 | if (*old_audio_status != new_audio_status) | ||
91 | { /* force a redraw if anything changed the audio status from outside */ | ||
92 | *old_audio_status = new_audio_status; | ||
93 | redraw_list = true; | ||
94 | } | ||
95 | return redraw_list; | ||
96 | } | ||
97 | |||
79 | static int get_menu_selection(int selected_item, const struct menu_item_ex *menu) | 98 | static int get_menu_selection(int selected_item, const struct menu_item_ex *menu) |
80 | { | 99 | { |
81 | int type = (menu->flags&MENU_TYPE_MASK); | 100 | int type = (menu->flags&MENU_TYPE_MASK); |
@@ -128,8 +147,7 @@ static const char* get_menu_item_name(int selected_item, | |||
128 | type = (menu->flags&MENU_TYPE_MASK); | 147 | type = (menu->flags&MENU_TYPE_MASK); |
129 | if ((type == MT_SETTING) || (type == MT_SETTING_W_TEXT)) | 148 | if ((type == MT_SETTING) || (type == MT_SETTING_W_TEXT)) |
130 | { | 149 | { |
131 | const struct settings_list *v | 150 | const struct settings_list *v = find_setting(menu->variable, NULL); |
132 | = find_setting(menu->variable, NULL); | ||
133 | if (v) | 151 | if (v) |
134 | return str(v->lang_id); | 152 | return str(v->lang_id); |
135 | else return "Not Done yet!"; | 153 | else return "Not Done yet!"; |
@@ -158,20 +176,13 @@ static enum themable_icons menu_get_icon(int selected_item, void * data) | |||
158 | 176 | ||
159 | if (menu_icon == Icon_NOICON) | 177 | if (menu_icon == Icon_NOICON) |
160 | { | 178 | { |
161 | switch (menu->flags&MENU_TYPE_MASK) | 179 | unsigned int flags = (menu->flags&MENU_TYPE_MASK); |
162 | { | 180 | if(flags == MT_MENU) |
163 | case MT_SETTING: | 181 | menu_icon = Icon_Submenu; |
164 | case MT_SETTING_W_TEXT: | 182 | else if (flags == MT_SETTING || flags == MT_SETTING_W_TEXT) |
165 | menu_icon = Icon_Menu_setting; | 183 | menu_icon = Icon_Menu_setting; |
166 | break; | 184 | else if (flags == MT_FUNCTION_CALL || flags == MT_RETURN_VALUE) |
167 | case MT_MENU: | 185 | menu_icon = Icon_Menu_functioncall; |
168 | menu_icon = Icon_Submenu; | ||
169 | break; | ||
170 | case MT_FUNCTION_CALL: | ||
171 | case MT_RETURN_VALUE: | ||
172 | menu_icon = Icon_Menu_functioncall; | ||
173 | break; | ||
174 | } | ||
175 | } | 186 | } |
176 | return menu_icon; | 187 | return menu_icon; |
177 | } | 188 | } |
@@ -368,12 +379,15 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
368 | struct viewport parent[NB_SCREENS], bool hide_theme) | 379 | struct viewport parent[NB_SCREENS], bool hide_theme) |
369 | { | 380 | { |
370 | int selected = start_selected? *start_selected : 0; | 381 | int selected = start_selected? *start_selected : 0; |
382 | int ret = 0; | ||
371 | int action; | 383 | int action; |
372 | struct gui_synclist lists; | 384 | struct gui_synclist lists; |
373 | const struct menu_item_ex *temp = NULL; | 385 | const struct menu_item_ex *temp = NULL; |
374 | const struct menu_item_ex *menu = start_menu; | 386 | const struct menu_item_ex *menu = start_menu; |
375 | int ret = 0; | 387 | |
388 | bool in_stringlist, done = false; | ||
376 | bool redraw_lists; | 389 | bool redraw_lists; |
390 | |||
377 | int old_audio_status = audio_status(); | 391 | int old_audio_status = audio_status(); |
378 | 392 | ||
379 | #ifdef HAVE_TOUCHSCREEN | 393 | #ifdef HAVE_TOUCHSCREEN |
@@ -386,10 +400,9 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
386 | FOR_NB_SCREENS(i) | 400 | FOR_NB_SCREENS(i) |
387 | viewportmanager_theme_enable(i, !hide_theme, NULL); | 401 | viewportmanager_theme_enable(i, !hide_theme, NULL); |
388 | 402 | ||
389 | const struct menu_item_ex *menu_stack[MAX_MENUS]; | 403 | struct menu_data_t mstack[MAX_MENUS]; /* menu, selected */ |
390 | int menu_stack_selected_item[MAX_MENUS]; | ||
391 | int stack_top = 0; | 404 | int stack_top = 0; |
392 | bool in_stringlist, done = false; | 405 | |
393 | struct viewport *vps = NULL; | 406 | struct viewport *vps = NULL; |
394 | menu_callback_type menu_callback = NULL; | 407 | menu_callback_type menu_callback = NULL; |
395 | 408 | ||
@@ -403,42 +416,30 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
403 | 416 | ||
404 | gui_synclist_draw(&lists); | 417 | gui_synclist_draw(&lists); |
405 | gui_synclist_speak_item(&lists); | 418 | gui_synclist_speak_item(&lists); |
419 | |||
406 | while (!done) | 420 | while (!done) |
407 | { | 421 | { |
408 | int new_audio_status; | ||
409 | redraw_lists = false; | ||
410 | keyclick_set_callback(gui_synclist_keyclick_callback, &lists); | 422 | keyclick_set_callback(gui_synclist_keyclick_callback, &lists); |
423 | |||
411 | action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, | 424 | action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, |
412 | list_do_action_timeout(&lists, HZ)); | 425 | list_do_action_timeout(&lists, HZ)); |
426 | /* HZ so the status bar redraws corectly */ | ||
413 | 427 | ||
414 | /* query audio status to see if it changed */ | 428 | /* query audio status to see if it changed */ |
415 | new_audio_status = audio_status(); | 429 | redraw_lists = query_audio_status(&old_audio_status); |
416 | if (old_audio_status != new_audio_status) | ||
417 | { /* force a redraw if anything changed the audio status | ||
418 | * from outside */ | ||
419 | redraw_lists = true; | ||
420 | old_audio_status = new_audio_status; | ||
421 | } | ||
422 | /* HZ so the status bar redraws corectly */ | ||
423 | 430 | ||
424 | if (menu_callback) | 431 | if (menu_callback) |
425 | { | 432 | { |
426 | int old_action = action; | 433 | int new_action = menu_callback(action, menu, &lists); |
427 | action = menu_callback(action, menu, &lists); | 434 | if (new_action == ACTION_EXIT_AFTER_THIS_MENUITEM) |
428 | if (action == ACTION_EXIT_AFTER_THIS_MENUITEM) | 435 | ret = MENU_SELECTED_EXIT; /* exit after return from selection */ |
429 | { | 436 | else if (new_action == ACTION_REDRAW) |
430 | action = old_action; | ||
431 | ret = MENU_SELECTED_EXIT; /* will exit after returning | ||
432 | from selection */ | ||
433 | } | ||
434 | else if (action == ACTION_REDRAW) | ||
435 | { | ||
436 | action = old_action; | ||
437 | redraw_lists = true; | 437 | redraw_lists = true; |
438 | } | 438 | else |
439 | action = new_action; | ||
439 | } | 440 | } |
440 | 441 | ||
441 | if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD)) | 442 | if (LIKELY(gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))) |
442 | continue; | 443 | continue; |
443 | #ifdef HAVE_QUICKSCREEN | 444 | #ifdef HAVE_QUICKSCREEN |
444 | else if (action == ACTION_STD_QUICKSCREEN) | 445 | else if (action == ACTION_STD_QUICKSCREEN) |
@@ -505,7 +506,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
505 | ID2P(LANG_ONPLAY_MENU_TITLE), NULL, | 506 | ID2P(LANG_ONPLAY_MENU_TITLE), NULL, |
506 | ID2P(LANG_RESET_SETTING)); | 507 | ID2P(LANG_RESET_SETTING)); |
507 | const struct menu_item_ex *menu; | 508 | const struct menu_item_ex *menu; |
508 | int menu_selection = 0; | ||
509 | const struct settings_list *setting = | 509 | const struct settings_list *setting = |
510 | find_setting(temp->variable, NULL); | 510 | find_setting(temp->variable, NULL); |
511 | #ifdef HAVE_QUICKSCREEN | 511 | #ifdef HAVE_QUICKSCREEN |
@@ -514,7 +514,10 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
514 | else | 514 | else |
515 | #endif | 515 | #endif |
516 | menu = ¬quickscreen_able_option; | 516 | menu = ¬quickscreen_able_option; |
517 | switch (do_menu(menu, &menu_selection, NULL, false)) | 517 | |
518 | int msel = do_menu(menu, NULL, NULL, false); | ||
519 | |||
520 | switch (msel) | ||
518 | { | 521 | { |
519 | case GO_TO_PREVIOUS: | 522 | case GO_TO_PREVIOUS: |
520 | break; | 523 | break; |
@@ -556,10 +559,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
556 | } | 559 | } |
557 | else if (action == ACTION_STD_CANCEL) | 560 | else if (action == ACTION_STD_CANCEL) |
558 | { | 561 | { |
559 | bool exiting_menu = false; | ||
560 | in_stringlist = false; | ||
561 | /* might be leaving list, so stop scrolling */ | 562 | /* might be leaving list, so stop scrolling */ |
562 | gui_synclist_scroll_stop(&lists); | 563 | gui_synclist_scroll_stop(&lists); |
564 | |||
565 | bool exiting_menu = false; | ||
566 | in_stringlist = false; | ||
567 | |||
563 | if (menu_callback) | 568 | if (menu_callback) |
564 | menu_callback(ACTION_EXIT_MENUITEM, menu, &lists); | 569 | menu_callback(ACTION_EXIT_MENUITEM, menu, &lists); |
565 | 570 | ||
@@ -567,15 +572,16 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
567 | done = true; | 572 | done = true; |
568 | else if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) | 573 | else if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) |
569 | exiting_menu = true; | 574 | exiting_menu = true; |
575 | |||
570 | if (stack_top > 0) | 576 | if (stack_top > 0) |
571 | { | 577 | { |
572 | stack_top--; | 578 | stack_top--; |
573 | menu = menu_stack[stack_top]; | 579 | menu = mstack[stack_top].menu; |
580 | int msel = mstack[stack_top].selected; | ||
574 | if (!exiting_menu && (menu->flags&MENU_EXITAFTERTHISMENU)) | 581 | if (!exiting_menu && (menu->flags&MENU_EXITAFTERTHISMENU)) |
575 | done = true; | 582 | done = true; |
576 | else | 583 | else |
577 | init_menu_lists(menu, &lists, | 584 | init_menu_lists(menu, &lists, msel, false, vps); |
578 | menu_stack_selected_item[stack_top], false, vps); | ||
579 | redraw_lists = true; | 585 | redraw_lists = true; |
580 | /* new menu, so reload the callback */ | 586 | /* new menu, so reload the callback */ |
581 | get_menu_callback(menu, &menu_callback); | 587 | get_menu_callback(menu, &menu_callback); |
@@ -588,19 +594,18 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
588 | } | 594 | } |
589 | else if (action == ACTION_STD_OK) | 595 | else if (action == ACTION_STD_OK) |
590 | { | 596 | { |
591 | int type = (menu->flags&MENU_TYPE_MASK); | ||
592 | /* entering an item that may not be a list, so stop scrolling */ | 597 | /* entering an item that may not be a list, so stop scrolling */ |
593 | gui_synclist_scroll_stop(&lists); | 598 | gui_synclist_scroll_stop(&lists); |
599 | redraw_lists = true; | ||
600 | |||
601 | int type = (menu->flags&MENU_TYPE_MASK); | ||
594 | selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu); | 602 | selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu); |
595 | if (type == MT_MENU) | 603 | if (type == MT_MENU) |
596 | temp = menu->submenus[selected]; | 604 | temp = menu->submenus[selected]; |
597 | else | 605 | else if (!in_stringlist) |
598 | type = -1; | 606 | type = -1; |
599 | 607 | ||
600 | redraw_lists = true; | 608 | if (!in_stringlist && temp) |
601 | if (in_stringlist) | ||
602 | type = (menu->flags&MENU_TYPE_MASK); | ||
603 | else if (temp) | ||
604 | { | 609 | { |
605 | type = (temp->flags&MENU_TYPE_MASK); | 610 | type = (temp->flags&MENU_TYPE_MASK); |
606 | get_menu_callback(temp, &menu_callback); | 611 | get_menu_callback(temp, &menu_callback); |
@@ -616,8 +621,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
616 | case MT_MENU: | 621 | case MT_MENU: |
617 | if (stack_top < MAX_MENUS) | 622 | if (stack_top < MAX_MENUS) |
618 | { | 623 | { |
619 | menu_stack[stack_top] = menu; | 624 | mstack[stack_top].menu = menu; |
620 | menu_stack_selected_item[stack_top] = selected; | 625 | mstack[stack_top].selected = selected; |
621 | stack_top++; | 626 | stack_top++; |
622 | menu = temp; | 627 | menu = temp; |
623 | init_menu_lists(menu, &lists, 0, true, vps); | 628 | init_menu_lists(menu, &lists, 0, true, vps); |
@@ -661,8 +666,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
661 | } | 666 | } |
662 | else if (stack_top < MAX_MENUS) | 667 | else if (stack_top < MAX_MENUS) |
663 | { | 668 | { |
664 | menu_stack[stack_top] = menu; | 669 | mstack[stack_top].menu = menu; |
665 | menu_stack_selected_item[stack_top] = selected; | 670 | mstack[stack_top].selected = selected; |
666 | stack_top++; | 671 | stack_top++; |
667 | menu = temp; | 672 | menu = temp; |
668 | init_menu_lists(menu,&lists,0,false, vps); | 673 | init_menu_lists(menu,&lists,0,false, vps); |
@@ -731,8 +736,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
731 | the selected item from the menu do_menu() was called from */ | 736 | the selected item from the menu do_menu() was called from */ |
732 | if (stack_top > 0) | 737 | if (stack_top > 0) |
733 | { | 738 | { |
734 | menu = menu_stack[0]; | 739 | menu = mstack[0].menu; |
735 | init_menu_lists(menu,&lists,menu_stack_selected_item[0],true, vps); | 740 | init_menu_lists(menu,&lists,mstack[0].selected,true, vps); |
736 | } | 741 | } |
737 | *start_selected = get_menu_selection( | 742 | *start_selected = get_menu_selection( |
738 | gui_synclist_get_sel_pos(&lists), menu); | 743 | gui_synclist_get_sel_pos(&lists), menu); |
@@ -748,6 +753,5 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
748 | tsm == old_global_mode)) | 753 | tsm == old_global_mode)) |
749 | touchscreen_set_mode(tsm); | 754 | touchscreen_set_mode(tsm); |
750 | #endif | 755 | #endif |
751 | |||
752 | return ret; | 756 | return ret; |
753 | } | 757 | } |