From dddd15746fce3a8610a60a6e7e84cf6fa8479f15 Mon Sep 17 00:00:00 2001 From: Steve Bavin Date: Tue, 15 Jun 2010 07:08:35 +0000 Subject: [PATCH] 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 --- apps/gui/list.c | 96 ++++++++++++++++++++++++------------------------- 1 file 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, gui_list->start_item[screen] = new_start_item; } +static void _gui_synclist_speak_item(struct gui_synclist *lists) +{ + list_speak_item *cb = lists->callback_speak_item; + if (cb && lists->nb_items != 0) + { + talk_shutup(); + /* If we have just very recently started talking, then we want + to stay silent for a while until things settle. Likewise if + we already had a pending scheduled announcement not yet due + we need to reschedule it. */ + if ((lists->scheduled_talk_tick && + TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) || + (lists->last_talked_tick && + TIME_BEFORE(current_tick, lists->last_talked_tick + HZ/5))) + { + lists->scheduled_talk_tick = current_tick + HZ/5; + } + else + { + lists->scheduled_talk_tick = 0; /* work done */ + cb(lists->selected_item, lists->data); + lists->last_talked_tick = current_tick; + } + } +} + +void gui_synclist_speak_item(struct gui_synclist *lists) +{ + if (global_settings.talk_menu) + { + if (lists->nb_items == 0) + talk_id(VOICE_EMPTY_LIST, true); + else + _gui_synclist_speak_item(lists); + } +} + /* * Selects an item in the list * - gui_list : the list structure @@ -302,7 +339,11 @@ void gui_synclist_select_item(struct gui_synclist * gui_list, int item_number) int i; if (item_number >= gui_list->nb_items || item_number < 0) return; - gui_list->selected_item = item_number; + if (item_number != gui_list->selected_item) + { + gui_list->selected_item = item_number; + _gui_synclist_speak_item(gui_list); + } FOR_NB_SCREENS(i) gui_list_put_selection_on_screen(gui_list, i); } @@ -320,12 +361,12 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, if (new_selection >= gui_list->nb_items) { - gui_list->selected_item = gui_list->limit_scroll ? + new_selection = gui_list->limit_scroll ? gui_list->nb_items - gui_list->selected_size : 0; } else if (new_selection < 0) { - gui_list->selected_item = gui_list->limit_scroll ? + new_selection = gui_list->limit_scroll ? 0 : gui_list->nb_items - gui_list->selected_size; } else if (gui_list->show_selection_marker == false) @@ -350,8 +391,7 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, } return; } - else gui_list->selected_item += offset; - gui_synclist_select_item(gui_list, gui_list->selected_item); + gui_synclist_select_item(gui_list, new_selection); } /* @@ -510,42 +550,6 @@ static void gui_synclist_scroll_left(struct gui_synclist * lists) } #endif /* HAVE_LCD_BITMAP */ -static void _gui_synclist_speak_item(struct gui_synclist *lists, bool repeating) -{ - list_speak_item *cb = lists->callback_speak_item; - if(cb && gui_synclist_get_nb_items(lists) != 0) - { - int sel = gui_synclist_get_sel_pos(lists); - talk_shutup(); - /* If we got a repeating key action, or we have just very - recently started talking, then we want to stay silent for a - while until things settle. Likewise if we already had a - pending scheduled announcement not yet due: we need to - reschedule it. */ - if(repeating - || (lists->scheduled_talk_tick - && TIME_BEFORE(current_tick, lists->scheduled_talk_tick)) - || (lists->last_talked_tick - && TIME_BEFORE(current_tick, lists->last_talked_tick +HZ/4))) - { - lists->scheduled_talk_tick = current_tick +HZ/4; - return; - } else { - lists->scheduled_talk_tick = 0; /* work done */ - cb(sel, lists->data); - lists->last_talked_tick = current_tick; - } - } -} -void gui_synclist_speak_item(struct gui_synclist * lists) -/* The list user should call this to speak the first item on entering - the list, and whenever the list is updated. */ -{ - if(gui_synclist_get_nb_items(lists) == 0 && global_settings.talk_menu) - talk_id(VOICE_EMPTY_LIST, true); - else _gui_synclist_speak_item(lists, false); -} - bool gui_synclist_do_button(struct gui_synclist * lists, int *actionptr, enum list_wrap wrap) { @@ -627,9 +631,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, if (button_queue_count() < FRAMEDROP_TRIGGER) #endif gui_synclist_draw(lists); - _gui_synclist_speak_item(lists, - action == ACTION_STD_PREVREPEAT - || next_item_modifier > 1); yield(); *actionptr = ACTION_STD_PREV; return true; @@ -641,9 +642,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, if (button_queue_count() < FRAMEDROP_TRIGGER) #endif gui_synclist_draw(lists); - _gui_synclist_speak_item(lists, - action == ACTION_STD_NEXTREPEAT - || next_item_modifier >1); yield(); *actionptr = ACTION_STD_NEXT; return true; @@ -691,7 +689,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, SCREEN_MAIN; gui_synclist_select_previous_page(lists, screen); gui_synclist_draw(lists); - _gui_synclist_speak_item(lists, false); yield(); *actionptr = ACTION_STD_NEXT; } @@ -707,7 +704,6 @@ bool gui_synclist_do_button(struct gui_synclist * lists, SCREEN_MAIN; gui_synclist_select_next_page(lists, screen); gui_synclist_draw(lists); - _gui_synclist_speak_item(lists, false); yield(); *actionptr = ACTION_STD_PREV; } @@ -716,7 +712,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists, if(lists->scheduled_talk_tick && TIME_AFTER(current_tick, lists->scheduled_talk_tick)) /* scheduled postponed item announcement is due */ - _gui_synclist_speak_item(lists, false); + _gui_synclist_speak_item(lists); return false; }