diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2018-12-15 19:15:28 -0500 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2019-01-31 15:25:35 +0100 |
commit | 39b64f7d4d29a31da3c4b376f4663c77468ca5b2 (patch) | |
tree | 2939e29e2f807d2980ba8e82bcb7a66653c32c85 /apps | |
parent | f7a2c72042cc40b641a2867f0fdff61ac7e3c56f (diff) | |
download | rockbox-39b64f7d4d29a31da3c4b376f4663c77468ca5b2.tar.gz rockbox-39b64f7d4d29a31da3c4b376f4663c77468ca5b2.zip |
FS#10311 -- Add beep when navigating to beginning or end of list.
Originally by Stephane Doyon.
Updated by Alex Wallis, Igor Poretsky, and myself.
Change-Id: I996f18043bd3377d5aeaf65f4290250ea2a6832b
Diffstat (limited to 'apps')
-rw-r--r-- | apps/gui/list.c | 74 | ||||
-rw-r--r-- | apps/misc.c | 7 | ||||
-rw-r--r-- | apps/misc.h | 2 |
3 files changed, 68 insertions, 15 deletions
diff --git a/apps/gui/list.c b/apps/gui/list.c index eb5f298316..b0d7829f9a 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c | |||
@@ -95,7 +95,7 @@ static void list_init_viewports(struct gui_synclist *list) | |||
95 | #else | 95 | #else |
96 | static struct viewport parent[NB_SCREENS] = | 96 | static struct viewport parent[NB_SCREENS] = |
97 | { | 97 | { |
98 | [SCREEN_MAIN] = | 98 | [SCREEN_MAIN] = |
99 | { | 99 | { |
100 | .x = 0, | 100 | .x = 0, |
101 | .y = 0, | 101 | .y = 0, |
@@ -117,7 +117,7 @@ static int list_nb_lines(struct gui_synclist *list, enum screen_type screen) | |||
117 | 117 | ||
118 | bool list_display_title(struct gui_synclist *list, enum screen_type screen) | 118 | bool list_display_title(struct gui_synclist *list, enum screen_type screen) |
119 | { | 119 | { |
120 | return list->title != NULL && | 120 | return list->title != NULL && |
121 | !sb_set_title_text(list->title, list->title_icon, screen) && | 121 | !sb_set_title_text(list->title, list->title_icon, screen) && |
122 | list_nb_lines(list, screen) > 2; | 122 | list_nb_lines(list, screen) > 2; |
123 | } | 123 | } |
@@ -161,8 +161,8 @@ void list_init_item_height(struct gui_synclist *list, enum screen_type screen) | |||
161 | * - callback_get_item_name : pointer to a function that associates a label | 161 | * - callback_get_item_name : pointer to a function that associates a label |
162 | * to a given item number | 162 | * to a given item number |
163 | * - data : extra data passed to the list callback | 163 | * - data : extra data passed to the list callback |
164 | * - scroll_all : | 164 | * - scroll_all : |
165 | * - selected_size : | 165 | * - selected_size : |
166 | * - parent : the parent viewports to use. NULL means the full screen minus | 166 | * - parent : the parent viewports to use. NULL means the full screen minus |
167 | * statusbar if enabled. NOTE: new screens should NOT set this to NULL. | 167 | * statusbar if enabled. NOTE: new screens should NOT set this to NULL. |
168 | */ | 168 | */ |
@@ -264,7 +264,7 @@ void gui_synclist_draw(struct gui_synclist *gui_list) | |||
264 | } | 264 | } |
265 | FOR_NB_SCREENS(i) | 265 | FOR_NB_SCREENS(i) |
266 | { | 266 | { |
267 | #ifdef HAVE_LCD_BITMAP | 267 | #ifdef HAVE_LCD_BITMAP |
268 | if (!skinlist_draw(&screens[i], gui_list)) | 268 | if (!skinlist_draw(&screens[i], gui_list)) |
269 | #endif | 269 | #endif |
270 | list_draw(&screens[i], gui_list); | 270 | list_draw(&screens[i], gui_list); |
@@ -320,6 +320,48 @@ static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list, | |||
320 | gui_list->start_item[screen] = new_start_item; | 320 | gui_list->start_item[screen] = new_start_item; |
321 | } | 321 | } |
322 | 322 | ||
323 | static void edge_beep(struct gui_synclist * gui_list, bool wrap) | ||
324 | { | ||
325 | #if CONFIG_CODEC != SWCODEC | ||
326 | (void)gui_list; | ||
327 | (void)wrap; | ||
328 | #else | ||
329 | if (global_settings.keyclick) | ||
330 | { | ||
331 | list_speak_item *cb = gui_list->callback_speak_item; | ||
332 | if (!wrap) /* a bounce */ | ||
333 | { | ||
334 | static long last_bounce_tick = 0; | ||
335 | if(TIME_BEFORE(current_tick, last_bounce_tick+HZ/4)) | ||
336 | return; | ||
337 | last_bounce_tick = current_tick; | ||
338 | } | ||
339 | /* Next thing the list code will do is go speak the item, doing | ||
340 | a talk_shutup() first. Shutup now so the beep is clearer, and | ||
341 | make sure the subsequent shutup is skipped because otherwise | ||
342 | it'd kill the pcm buffer. */ | ||
343 | if (cb) { | ||
344 | talk_shutup(); | ||
345 | talk_force_enqueue_next(); | ||
346 | } | ||
347 | system_sound_play(wrap ? SOUND_LIST_EDGE_BEEP_WRAP : SOUND_LIST_EDGE_BEEP_NOWRAP); | ||
348 | if (cb) { | ||
349 | /* On at least x5: if, instead of the above shutup, I insert a | ||
350 | sleep just after the beep_play() call, to delay the subsequent | ||
351 | shutup and talk, then in some cases the beep is not played: if | ||
352 | the end of a previous utterance is still playing from the pcm buf, | ||
353 | the beep fails, even if there would seem to remain enough time | ||
354 | to the utterance to mix in the beep. */ | ||
355 | |||
356 | /* Somehow, the following voice utterance is suppressed on e200, | ||
357 | but not on x5. Work around... */ | ||
358 | sleep((40*HZ +999)/1000); // FIXME: Is this really needed? | ||
359 | talk_force_shutup(); | ||
360 | } | ||
361 | } | ||
362 | #endif | ||
363 | } | ||
364 | |||
323 | static void _gui_synclist_speak_item(struct gui_synclist *lists) | 365 | static void _gui_synclist_speak_item(struct gui_synclist *lists) |
324 | { | 366 | { |
325 | list_speak_item *cb = lists->callback_speak_item; | 367 | list_speak_item *cb = lists->callback_speak_item; |
@@ -330,13 +372,13 @@ static void _gui_synclist_speak_item(struct gui_synclist *lists) | |||
330 | to stay silent for a while until things settle. Likewise if | 372 | to stay silent for a while until things settle. Likewise if |
331 | we already had a pending scheduled announcement not yet due | 373 | we already had a pending scheduled announcement not yet due |
332 | we need to reschedule it. */ | 374 | we need to reschedule it. */ |
333 | if ((lists->scheduled_talk_tick && | 375 | if ((lists->scheduled_talk_tick && |
334 | TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) || | 376 | TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) || |
335 | (lists->last_talked_tick && | 377 | (lists->last_talked_tick && |
336 | TIME_BEFORE(current_tick, lists->last_talked_tick + HZ/5))) | 378 | TIME_BEFORE(current_tick, lists->last_talked_tick + HZ/5))) |
337 | { | 379 | { |
338 | lists->scheduled_talk_tick = current_tick + HZ/5; | 380 | lists->scheduled_talk_tick = current_tick + HZ/5; |
339 | } | 381 | } |
340 | else | 382 | else |
341 | { | 383 | { |
342 | lists->scheduled_talk_tick = 0; /* work done */ | 384 | lists->scheduled_talk_tick = 0; /* work done */ |
@@ -390,11 +432,13 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, | |||
390 | { | 432 | { |
391 | new_selection = gui_list->limit_scroll ? | 433 | new_selection = gui_list->limit_scroll ? |
392 | gui_list->nb_items - gui_list->selected_size : 0; | 434 | gui_list->nb_items - gui_list->selected_size : 0; |
435 | edge_beep(gui_list, !gui_list->limit_scroll); | ||
393 | } | 436 | } |
394 | else if (new_selection < 0) | 437 | else if (new_selection < 0) |
395 | { | 438 | { |
396 | new_selection = gui_list->limit_scroll ? | 439 | new_selection = gui_list->limit_scroll ? |
397 | 0 : gui_list->nb_items - gui_list->selected_size; | 440 | 0 : gui_list->nb_items - gui_list->selected_size; |
441 | edge_beep(gui_list, !gui_list->limit_scroll); | ||
398 | } | 442 | } |
399 | else if (gui_list->show_selection_marker == false) | 443 | else if (gui_list->show_selection_marker == false) |
400 | { | 444 | { |
@@ -404,13 +448,13 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, | |||
404 | if (offset > 0) | 448 | if (offset > 0) |
405 | { | 449 | { |
406 | int screen_top = MAX(0, gui_list->nb_items - nb_lines); | 450 | int screen_top = MAX(0, gui_list->nb_items - nb_lines); |
407 | gui_list->start_item[i] = MIN(screen_top, gui_list->start_item[i] + | 451 | gui_list->start_item[i] = MIN(screen_top, gui_list->start_item[i] + |
408 | gui_list->selected_size); | 452 | gui_list->selected_size); |
409 | gui_list->selected_item = gui_list->start_item[i]; | 453 | gui_list->selected_item = gui_list->start_item[i]; |
410 | } | 454 | } |
411 | else | 455 | else |
412 | { | 456 | { |
413 | gui_list->start_item[i] = MAX(0, gui_list->start_item[i] - | 457 | gui_list->start_item[i] = MAX(0, gui_list->start_item[i] - |
414 | gui_list->selected_size); | 458 | gui_list->selected_size); |
415 | gui_list->selected_item = gui_list->start_item[i] + nb_lines; | 459 | gui_list->selected_item = gui_list->start_item[i] + nb_lines; |
416 | } | 460 | } |
@@ -549,7 +593,7 @@ void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll) | |||
549 | #ifdef HAVE_LCD_BITMAP | 593 | #ifdef HAVE_LCD_BITMAP |
550 | /* | 594 | /* |
551 | * Makes all the item in the list scroll by one step to the right. | 595 | * Makes all the item in the list scroll by one step to the right. |
552 | * Should stop increasing the value when reaching the widest item value | 596 | * Should stop increasing the value when reaching the widest item value |
553 | * in the list. | 597 | * in the list. |
554 | */ | 598 | */ |
555 | static void gui_synclist_scroll_right(struct gui_synclist * lists) | 599 | static void gui_synclist_scroll_right(struct gui_synclist * lists) |
@@ -765,7 +809,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
765 | int screen = | 809 | int screen = |
766 | #ifdef HAVE_REMOTE_LCD | 810 | #ifdef HAVE_REMOTE_LCD |
767 | get_action_statuscode(NULL)&ACTION_REMOTE ? | 811 | get_action_statuscode(NULL)&ACTION_REMOTE ? |
768 | SCREEN_REMOTE : | 812 | SCREEN_REMOTE : |
769 | #endif | 813 | #endif |
770 | SCREEN_MAIN; | 814 | SCREEN_MAIN; |
771 | gui_synclist_select_previous_page(lists, screen); | 815 | gui_synclist_select_previous_page(lists, screen); |
@@ -780,7 +824,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
780 | int screen = | 824 | int screen = |
781 | #ifdef HAVE_REMOTE_LCD | 825 | #ifdef HAVE_REMOTE_LCD |
782 | get_action_statuscode(NULL)&ACTION_REMOTE ? | 826 | get_action_statuscode(NULL)&ACTION_REMOTE ? |
783 | SCREEN_REMOTE : | 827 | SCREEN_REMOTE : |
784 | #endif | 828 | #endif |
785 | SCREEN_MAIN; | 829 | SCREEN_MAIN; |
786 | gui_synclist_select_next_page(lists, screen); | 830 | gui_synclist_select_next_page(lists, screen); |
@@ -804,7 +848,7 @@ int list_do_action_timeout(struct gui_synclist *lists, int timeout) | |||
804 | if (lists != current_lists) | 848 | if (lists != current_lists) |
805 | { | 849 | { |
806 | if (!ui_update_event_registered) | 850 | if (!ui_update_event_registered) |
807 | ui_update_event_registered = | 851 | ui_update_event_registered = |
808 | add_event(GUI_EVENT_NEED_UI_UPDATE, _lists_uiviewport_update_callback); | 852 | add_event(GUI_EVENT_NEED_UI_UPDATE, _lists_uiviewport_update_callback); |
809 | current_lists = lists; | 853 | current_lists = lists; |
810 | } | 854 | } |
@@ -902,7 +946,7 @@ bool simplelist_show_list(struct simplelist_info *info) | |||
902 | FOR_NB_SCREENS(i) | 946 | FOR_NB_SCREENS(i) |
903 | viewportmanager_theme_enable(i, true, NULL); | 947 | viewportmanager_theme_enable(i, true, NULL); |
904 | 948 | ||
905 | gui_synclist_init(&lists, getname, info->callback_data, | 949 | gui_synclist_init(&lists, getname, info->callback_data, |
906 | info->scroll_all, info->selection_size, NULL); | 950 | info->scroll_all, info->selection_size, NULL); |
907 | 951 | ||
908 | if (info->title) | 952 | if (info->title) |
diff --git a/apps/misc.c b/apps/misc.c index 2106d11164..8b1668b63c 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -921,6 +921,13 @@ void system_sound_play(enum system_sound sound) | |||
921 | [SOUND_TRACK_NO_MORE] = | 921 | [SOUND_TRACK_NO_MORE] = |
922 | { &global_settings.beep, | 922 | { &global_settings.beep, |
923 | 1000, 100, 1500 }, | 923 | 1000, 100, 1500 }, |
924 | [SOUND_LIST_EDGE_BEEP_NOWRAP] = | ||
925 | { &global_settings.keyclick, | ||
926 | 1000, 40, 1500 }, | ||
927 | [SOUND_LIST_EDGE_BEEP_WRAP] = | ||
928 | { &global_settings.keyclick, | ||
929 | 2000, 20, 1500 }, | ||
930 | |||
924 | }; | 931 | }; |
925 | 932 | ||
926 | const struct beep_params *params = &beep_params[sound]; | 933 | const struct beep_params *params = &beep_params[sound]; |
diff --git a/apps/misc.h b/apps/misc.h index 25e9d17b9c..8d72e79a3d 100644 --- a/apps/misc.h +++ b/apps/misc.h | |||
@@ -190,6 +190,8 @@ enum system_sound | |||
190 | SOUND_KEYCLICK = 0, | 190 | SOUND_KEYCLICK = 0, |
191 | SOUND_TRACK_SKIP, | 191 | SOUND_TRACK_SKIP, |
192 | SOUND_TRACK_NO_MORE, | 192 | SOUND_TRACK_NO_MORE, |
193 | SOUND_LIST_EDGE_BEEP_WRAP, | ||
194 | SOUND_LIST_EDGE_BEEP_NOWRAP, | ||
193 | }; | 195 | }; |
194 | 196 | ||
195 | /* Play a standard sound */ | 197 | /* Play a standard sound */ |