diff options
author | Steve Bavin <pondlife@pondlife.me> | 2010-06-15 07:08:35 +0000 |
---|---|---|
committer | Steve Bavin <pondlife@pondlife.me> | 2010-06-15 07:08:35 +0000 |
commit | dddd15746fce3a8610a60a6e7e84cf6fa8479f15 (patch) | |
tree | 7db0b0ae4bbe1b6cbdb4f115094da8bd814a37a2 /apps/gui | |
parent | f98ea7142ee4820d57c83c244515d6d5478f20dd (diff) | |
download | rockbox-dddd15746fce3a8610a60a6e7e84cf6fa8479f15.tar.gz rockbox-dddd15746fce3a8610a60a6e7e84cf6fa8479f15.zip |
FS#10336 - Simplify list redrawing to improve voicing when scrolling to top/bottom.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26853 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/list.c | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/apps/gui/list.c b/apps/gui/list.c index ef2711d7c9..b39684ff92 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c | |||
@@ -292,6 +292,43 @@ static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list, | |||
292 | gui_list->start_item[screen] = new_start_item; | 292 | gui_list->start_item[screen] = new_start_item; |
293 | } | 293 | } |
294 | 294 | ||
295 | static void _gui_synclist_speak_item(struct gui_synclist *lists) | ||
296 | { | ||
297 | list_speak_item *cb = lists->callback_speak_item; | ||
298 | if (cb && lists->nb_items != 0) | ||
299 | { | ||
300 | talk_shutup(); | ||
301 | /* If we have just very recently started talking, then we want | ||
302 | to stay silent for a while until things settle. Likewise if | ||
303 | we already had a pending scheduled announcement not yet due | ||
304 | we need to reschedule it. */ | ||
305 | if ((lists->scheduled_talk_tick && | ||
306 | TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) || | ||
307 | (lists->last_talked_tick && | ||
308 | TIME_BEFORE(current_tick, lists->last_talked_tick + HZ/5))) | ||
309 | { | ||
310 | lists->scheduled_talk_tick = current_tick + HZ/5; | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | lists->scheduled_talk_tick = 0; /* work done */ | ||
315 | cb(lists->selected_item, lists->data); | ||
316 | lists->last_talked_tick = current_tick; | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | |||
321 | void gui_synclist_speak_item(struct gui_synclist *lists) | ||
322 | { | ||
323 | if (global_settings.talk_menu) | ||
324 | { | ||
325 | if (lists->nb_items == 0) | ||
326 | talk_id(VOICE_EMPTY_LIST, true); | ||
327 | else | ||
328 | _gui_synclist_speak_item(lists); | ||
329 | } | ||
330 | } | ||
331 | |||
295 | /* | 332 | /* |
296 | * Selects an item in the list | 333 | * Selects an item in the list |
297 | * - gui_list : the list structure | 334 | * - gui_list : the list structure |
@@ -302,7 +339,11 @@ void gui_synclist_select_item(struct gui_synclist * gui_list, int item_number) | |||
302 | int i; | 339 | int i; |
303 | if (item_number >= gui_list->nb_items || item_number < 0) | 340 | if (item_number >= gui_list->nb_items || item_number < 0) |
304 | return; | 341 | return; |
305 | gui_list->selected_item = item_number; | 342 | if (item_number != gui_list->selected_item) |
343 | { | ||
344 | gui_list->selected_item = item_number; | ||
345 | _gui_synclist_speak_item(gui_list); | ||
346 | } | ||
306 | FOR_NB_SCREENS(i) | 347 | FOR_NB_SCREENS(i) |
307 | gui_list_put_selection_on_screen(gui_list, i); | 348 | gui_list_put_selection_on_screen(gui_list, i); |
308 | } | 349 | } |
@@ -320,12 +361,12 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, | |||
320 | 361 | ||
321 | if (new_selection >= gui_list->nb_items) | 362 | if (new_selection >= gui_list->nb_items) |
322 | { | 363 | { |
323 | gui_list->selected_item = gui_list->limit_scroll ? | 364 | new_selection = gui_list->limit_scroll ? |
324 | gui_list->nb_items - gui_list->selected_size : 0; | 365 | gui_list->nb_items - gui_list->selected_size : 0; |
325 | } | 366 | } |
326 | else if (new_selection < 0) | 367 | else if (new_selection < 0) |
327 | { | 368 | { |
328 | gui_list->selected_item = gui_list->limit_scroll ? | 369 | new_selection = gui_list->limit_scroll ? |
329 | 0 : gui_list->nb_items - gui_list->selected_size; | 370 | 0 : gui_list->nb_items - gui_list->selected_size; |
330 | } | 371 | } |
331 | else if (gui_list->show_selection_marker == false) | 372 | else if (gui_list->show_selection_marker == false) |
@@ -350,8 +391,7 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, | |||
350 | } | 391 | } |
351 | return; | 392 | return; |
352 | } | 393 | } |
353 | else gui_list->selected_item += offset; | 394 | gui_synclist_select_item(gui_list, new_selection); |
354 | gui_synclist_select_item(gui_list, gui_list->selected_item); | ||
355 | } | 395 | } |
356 | 396 | ||
357 | /* | 397 | /* |
@@ -510,42 +550,6 @@ static void gui_synclist_scroll_left(struct gui_synclist * lists) | |||
510 | } | 550 | } |
511 | #endif /* HAVE_LCD_BITMAP */ | 551 | #endif /* HAVE_LCD_BITMAP */ |
512 | 552 | ||
513 | static void _gui_synclist_speak_item(struct gui_synclist *lists, bool repeating) | ||
514 | { | ||
515 | list_speak_item *cb = lists->callback_speak_item; | ||
516 | if(cb && gui_synclist_get_nb_items(lists) != 0) | ||
517 | { | ||
518 | int sel = gui_synclist_get_sel_pos(lists); | ||
519 | talk_shutup(); | ||
520 | /* If we got a repeating key action, or we have just very | ||
521 | recently started talking, then we want to stay silent for a | ||
522 | while until things settle. Likewise if we already had a | ||
523 | pending scheduled announcement not yet due: we need to | ||
524 | reschedule it. */ | ||
525 | if(repeating | ||
526 | || (lists->scheduled_talk_tick | ||
527 | && TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) | ||
528 | || (lists->last_talked_tick | ||
529 | && TIME_BEFORE(current_tick, lists->last_talked_tick +HZ/4))) | ||
530 | { | ||
531 | lists->scheduled_talk_tick = current_tick +HZ/4; | ||
532 | return; | ||
533 | } else { | ||
534 | lists->scheduled_talk_tick = 0; /* work done */ | ||
535 | cb(sel, lists->data); | ||
536 | lists->last_talked_tick = current_tick; | ||
537 | } | ||
538 | } | ||
539 | } | ||
540 | void gui_synclist_speak_item(struct gui_synclist * lists) | ||
541 | /* The list user should call this to speak the first item on entering | ||
542 | the list, and whenever the list is updated. */ | ||
543 | { | ||
544 | if(gui_synclist_get_nb_items(lists) == 0 && global_settings.talk_menu) | ||
545 | talk_id(VOICE_EMPTY_LIST, true); | ||
546 | else _gui_synclist_speak_item(lists, false); | ||
547 | } | ||
548 | |||
549 | bool gui_synclist_do_button(struct gui_synclist * lists, | 553 | bool gui_synclist_do_button(struct gui_synclist * lists, |
550 | int *actionptr, enum list_wrap wrap) | 554 | int *actionptr, enum list_wrap wrap) |
551 | { | 555 | { |
@@ -627,9 +631,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
627 | if (button_queue_count() < FRAMEDROP_TRIGGER) | 631 | if (button_queue_count() < FRAMEDROP_TRIGGER) |
628 | #endif | 632 | #endif |
629 | gui_synclist_draw(lists); | 633 | gui_synclist_draw(lists); |
630 | _gui_synclist_speak_item(lists, | ||
631 | action == ACTION_STD_PREVREPEAT | ||
632 | || next_item_modifier > 1); | ||
633 | yield(); | 634 | yield(); |
634 | *actionptr = ACTION_STD_PREV; | 635 | *actionptr = ACTION_STD_PREV; |
635 | return true; | 636 | return true; |
@@ -641,9 +642,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
641 | if (button_queue_count() < FRAMEDROP_TRIGGER) | 642 | if (button_queue_count() < FRAMEDROP_TRIGGER) |
642 | #endif | 643 | #endif |
643 | gui_synclist_draw(lists); | 644 | gui_synclist_draw(lists); |
644 | _gui_synclist_speak_item(lists, | ||
645 | action == ACTION_STD_NEXTREPEAT | ||
646 | || next_item_modifier >1); | ||
647 | yield(); | 645 | yield(); |
648 | *actionptr = ACTION_STD_NEXT; | 646 | *actionptr = ACTION_STD_NEXT; |
649 | return true; | 647 | return true; |
@@ -691,7 +689,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
691 | SCREEN_MAIN; | 689 | SCREEN_MAIN; |
692 | gui_synclist_select_previous_page(lists, screen); | 690 | gui_synclist_select_previous_page(lists, screen); |
693 | gui_synclist_draw(lists); | 691 | gui_synclist_draw(lists); |
694 | _gui_synclist_speak_item(lists, false); | ||
695 | yield(); | 692 | yield(); |
696 | *actionptr = ACTION_STD_NEXT; | 693 | *actionptr = ACTION_STD_NEXT; |
697 | } | 694 | } |
@@ -707,7 +704,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
707 | SCREEN_MAIN; | 704 | SCREEN_MAIN; |
708 | gui_synclist_select_next_page(lists, screen); | 705 | gui_synclist_select_next_page(lists, screen); |
709 | gui_synclist_draw(lists); | 706 | gui_synclist_draw(lists); |
710 | _gui_synclist_speak_item(lists, false); | ||
711 | yield(); | 707 | yield(); |
712 | *actionptr = ACTION_STD_PREV; | 708 | *actionptr = ACTION_STD_PREV; |
713 | } | 709 | } |
@@ -716,7 +712,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists, | |||
716 | if(lists->scheduled_talk_tick | 712 | if(lists->scheduled_talk_tick |
717 | && TIME_AFTER(current_tick, lists->scheduled_talk_tick)) | 713 | && TIME_AFTER(current_tick, lists->scheduled_talk_tick)) |
718 | /* scheduled postponed item announcement is due */ | 714 | /* scheduled postponed item announcement is due */ |
719 | _gui_synclist_speak_item(lists, false); | 715 | _gui_synclist_speak_item(lists); |
720 | return false; | 716 | return false; |
721 | } | 717 | } |
722 | 718 | ||