Index: trunk/apps/lang/english.lang
===================================================================
--- trunk.orig/apps/lang/english.lang
+++ trunk/apps/lang/english.lang
@@ -11417,3 +11417,17 @@
*: "Blank"
+
+ id: VOICE_EMPTY_LIST
+ desc: spoken only, when a list dialog contains no elements
+ user:
+
+ *: ""
+
+
+ *: ""
+
+
+ *: "Empty list"
+
+
Index: trunk/apps/gui/list.c
===================================================================
--- trunk.orig/apps/gui/list.c
+++ trunk/apps/gui/list.c
@@ -36,6 +36,7 @@
#include "lang.h"
#include "sound.h"
#include "misc.h"
+#include "talk.h"
#ifdef HAVE_LCD_CHARCELLS
#define SCROLL_LIMIT 1
@@ -78,6 +79,7 @@ static void gui_list_init(struct gui_lis
{
gui_list->callback_get_item_icon = NULL;
gui_list->callback_get_item_name = callback_get_item_name;
+ gui_list->callback_speak_item = NULL;
gui_list->display = NULL;
gui_list_set_nb_items(gui_list, 0);
gui_list->selected_item = 0;
@@ -96,6 +98,7 @@ static void gui_list_init(struct gui_lis
gui_list->last_displayed_selected_item = -1 ;
gui_list->last_displayed_start_item = -1 ;
+ gui_list->scheduled_talk_tick = gui_list->last_talked_tick = 0;
gui_list->show_selection_marker = true;
#ifdef HAVE_LCD_COLOR
@@ -825,6 +828,12 @@ void gui_synclist_set_icon_callback(stru
}
}
+void gui_synclist_set_voice_callback(struct gui_synclist * lists,
+ list_speak_item voice_callback)
+{
+ gui_list_set_voice_callback(&(lists->gui_list[0]), voice_callback);
+}
+
void gui_synclist_draw(struct gui_synclist * lists)
{
int i;
@@ -909,6 +918,43 @@ static void gui_synclist_scroll_left(str
}
#endif /* HAVE_LCD_BITMAP */
+static void _gui_synclist_speak_item(struct gui_synclist *lists, bool repeating)
+{
+ struct gui_list *l = &lists->gui_list[0];
+ list_speak_item *cb = l->callback_speak_item;
+ if(cb && gui_synclist_get_nb_items(lists) != 0)
+ {
+ int sel = gui_synclist_get_sel_pos(lists);
+ 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
+ || (l->scheduled_talk_tick
+ && TIME_BEFORE(current_tick, l->scheduled_talk_tick))
+ || (l->last_talked_tick
+ && TIME_BEFORE(current_tick, l->last_talked_tick +HZ/4)))
+ {
+ l->scheduled_talk_tick = current_tick +HZ/4;
+ return;
+ } else {
+ l->scheduled_talk_tick = 0; /* work done */
+ cb(sel, l->data);
+ l->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 && talk_menus_enabled())
+ talk_id(VOICE_EMPTY_LIST, true);
+ else _gui_synclist_speak_item(lists, false);
+}
+
extern intptr_t get_action_data(void);
bool gui_synclist_do_button(struct gui_synclist * lists,
@@ -987,9 +1033,10 @@ bool gui_synclist_do_button(struct gui_s
#ifndef HAVE_SCROLLWHEEL
if (queue_count(&button_queue) < 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;
@@ -1001,9 +1048,10 @@ bool gui_synclist_do_button(struct gui_s
#ifndef HAVE_SCROLLWHEEL
if (queue_count(&button_queue) < 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;
@@ -1052,6 +1100,7 @@ bool gui_synclist_do_button(struct gui_s
SCREEN_MAIN;
gui_synclist_select_previous_page(lists, screen);
gui_synclist_draw(lists);
+ _gui_synclist_speak_item(lists, false);
yield();
*actionptr = ACTION_STD_NEXT;
}
@@ -1067,10 +1116,44 @@ bool gui_synclist_do_button(struct gui_s
SCREEN_MAIN;
gui_synclist_select_next_page(lists, screen);
gui_synclist_draw(lists);
+ _gui_synclist_speak_item(lists, false);
yield();
*actionptr = ACTION_STD_PREV;
}
return true;
}
+ if(lists->gui_list[0].scheduled_talk_tick
+ && TIME_AFTER(current_tick, lists->gui_list[0].scheduled_talk_tick))
+ /* scheduled postponed item announcement is due */
+ _gui_synclist_speak_item(lists, false);
return false;
}
+
+int list_do_action_timeout(struct gui_synclist *lists, int timeout)
+/* Returns the lowest of timeout or the delay until a postponed
+ scheduled announcement is due (if any). */
+{
+ if(lists->gui_list[0].scheduled_talk_tick)
+ {
+ long delay = lists->gui_list[0].scheduled_talk_tick -current_tick +1;
+ /* +1 because the trigger condition uses TIME_AFTER(), which
+ is implemented as strictly greater than. */
+ if(delay < 0)
+ delay = 0;
+ if(timeout > delay || timeout == TIMEOUT_BLOCK)
+ timeout = delay;
+ }
+ return timeout;
+}
+
+bool list_do_action(int context, int timeout,
+ struct gui_synclist *lists, int *action,
+ enum list_wrap wrap)
+/* Combines the get_action() (with possibly overridden timeout) and
+ gui_synclist_do_button() calls. Returns the list action from
+ do_button, and places the action from get_action in *action. */
+{
+ timeout = list_do_action_timeout(lists, timeout);
+ *action = get_action(context, timeout);
+ return gui_synclist_do_button(lists, action, wrap);
+}
Index: trunk/apps/gui/list.h
===================================================================
--- trunk.orig/apps/gui/list.h
+++ trunk/apps/gui/list.h
@@ -62,6 +62,14 @@ typedef enum themable_icons list_get_ico
* Returns a pointer to a string that contains the text to display
*/
typedef char * list_get_name(int selected_item, void * data, char * buffer);
+/*
+ * Voice callback
+ * - selected_item : an integer that tells the number of the item to speak
+ * - data : a void pointer to the data you gave to the list when you
+ * initialized it
+ * Returns an integer, 0 means success, ignored really...
+ */
+typedef int list_speak_item(int selected_item, void * data);
#ifdef HAVE_LCD_COLOR
/*
* Color callback
@@ -98,9 +106,11 @@ struct gui_list
#endif
/* Cache the width of the title string in pixels/characters */
int title_width;
+ long scheduled_talk_tick, last_talked_tick;
list_get_icon *callback_get_item_icon;
list_get_name *callback_get_item_name;
+ list_speak_item *callback_speak_item;
struct screen * display;
/* The data that will be passed to the callback function YOU implement */
@@ -141,6 +151,14 @@ struct gui_list
#define gui_list_set_icon_callback(gui_list, _callback) \
(gui_list)->callback_get_item_icon=_callback
+/*
+ * Sets the voice callback function
+ * - gui_list : the list structure
+ * - _callback : the callback function
+ */
+#define gui_list_set_voice_callback(gui_list, _callback) \
+ (gui_list)->callback_speak_item=_callback
+
#ifdef HAVE_LCD_COLOR
/*
* Sets the color callback function
@@ -201,6 +219,8 @@ extern void gui_synclist_init(
);
extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items);
extern void gui_synclist_set_icon_callback(struct gui_synclist * lists, list_get_icon icon_callback);
+extern void gui_synclist_set_voice_callback(struct gui_synclist * lists, list_speak_item voice_callback);
+extern void gui_synclist_speak_item(struct gui_synclist * lists);
extern int gui_synclist_get_nb_items(struct gui_synclist * lists);
extern int gui_synclist_get_sel_pos(struct gui_synclist * lists);
@@ -225,4 +245,15 @@ extern bool gui_synclist_do_button(struc
unsigned *action,
enum list_wrap);
+/* If the list has a pending postponed scheduled announcement, that
+ may become due before the next get_action tmieout. This function
+ adjusts the get_action timeout appropriately. */
+extern int list_do_action_timeout(struct gui_synclist *lists, int timeout);
+/* This one combines a get_action call (with timeout overridden by
+ list_do_action_timeout) with the gui_synclist_do_button call, for
+ convenience. */
+extern bool list_do_action(int context, int timeout,
+ struct gui_synclist *lists, int *action,
+ enum list_wrap wrap);
+
#endif /* _GUI_LIST_H_ */
Index: trunk/apps/tree.c
===================================================================
--- trunk.orig/apps/tree.c
+++ trunk/apps/tree.c
@@ -111,9 +111,9 @@ static bool start_wps = false;
static int curr_context = false;/* id3db or tree*/
static int dirbrowse(void);
-static int ft_play_filenumber(int pos, int attr);
static int ft_play_dirname(char* name);
static void ft_play_filename(char *dir, char *file);
+static void say_filetype(int attr);
/*
* removes the extension of filename (if it doesn't start with a .)
@@ -216,6 +216,69 @@ static int tree_get_fileicon(int selecte
}
}
+static int tree_voice_cb(int selected_item, void * data)
+{
+ struct tree_context * local_tc=(struct tree_context *)data;
+ char *name;
+ int attr=0;
+#ifdef HAVE_TAGCACHE
+ bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
+
+ if (id3db)
+ {
+ attr = tagtree_get_attr(local_tc);
+ name = tagtree_get_entry(local_tc, selected_item)->name;
+ }
+ else
+#endif
+ {
+ struct entry* dc = local_tc->dircache;
+ struct entry* e = &dc[selected_item];
+ name = e->name;
+ attr = e->attr;
+ }
+ bool is_dir = (attr & ATTR_DIRECTORY);
+ bool did_clip = false;
+ /* First the .talk clip case */
+ if(is_dir)
+ {
+ if(global_settings.talk_dir_clip)
+ {
+ DEBUGF("Playing directory thumbnail: %s", local_tc->currdir);
+ did_clip = true;
+ if(ft_play_dirname(name) <0)
+ /* failed, not existing */
+ did_clip = false;
+ }
+ } else { /* it's a file */
+ if (global_settings.talk_file_clip && (attr & FILE_ATTR_THUMBNAIL))
+ {
+ did_clip = true;
+ DEBUGF("Playing file thumbnail: %s/%s%s\n",
+ local_tc->currdir, name, file_thumbnail_ext);
+ ft_play_filename(local_tc->currdir, name);
+ }
+ }
+ if(!did_clip)
+ {
+ /* say the number or spell if required or as a fallback */
+ switch (is_dir ? global_settings.talk_dir : global_settings.talk_file)
+ {
+ case 1: /* as numbers */
+ talk_id(is_dir ? VOICE_DIR : VOICE_FILE, false);
+ talk_number(selected_item+1 - (is_dir ? 0 : local_tc->dirsindir),
+ true);
+ if(!is_dir)
+ say_filetype(attr);
+ break;
+ case 2: /* spelled */
+ talk_spell(name, false);
+ break;
+ }
+ }
+ return 0;
+}
+
bool check_rockboxdir(void)
{
DIR *dir = opendir(ROCKBOX_DIR);
@@ -255,6 +318,9 @@ void tree_gui_init(void)
gui_buttonbar_set_display(&tree_buttonbar, &(screens[SCREEN_MAIN]) );
#endif
gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1);
+ if(global_settings.talk_dir || global_settings.talk_dir_clip
+ || global_settings.talk_file || global_settings.talk_file_clip)
+ gui_synclist_set_voice_callback(&tree_lists, tree_voice_cb);
gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon);
#ifdef HAVE_LCD_COLOR
gui_list_set_color_callback(&tree_lists.gui_list[SCREEN_MAIN],
@@ -269,8 +335,6 @@ struct tree_context* tree_get_context(vo
return &tc;
}
-/* talkbox hovering delay, to avoid immediate disk activity */
-#define HOVER_DELAY (HZ/2)
/*
* Returns the position of a given file in the current directory
* returns -1 if not found
@@ -424,6 +488,7 @@ static int update_dir(void)
}
#endif
gui_synclist_draw(&tree_lists);
+ gui_synclist_speak_item(&tree_lists);
gui_syncstatusbar_draw(&statusbars, true);
return tc.filesindir;
}
@@ -551,14 +616,11 @@ static int dirbrowse()
{
int numentries=0;
char buf[MAX_PATH];
- int lasti = -1;
unsigned button, oldbutton;
bool reload_root = false;
int lastfilter = *tc.dirfilter;
bool lastsortcase = global_settings.sort_case;
- bool need_update = true;
bool exit_func = false;
- long thumbnail_time = -1; /* for delaying a thumbnail */
char* currdir = tc.currdir; /* just a shortcut */
#ifdef HAVE_TAGCACHE
@@ -580,6 +642,7 @@ static int dirbrowse()
start_wps = false;
numentries = update_dir();
+ reload_dir = false;
if (numentries == -1)
return false; /* currdir is not a directory */
@@ -604,9 +667,10 @@ static int dirbrowse()
boot_changed = false;
}
#endif
- button = get_action(CONTEXT_TREE,HZ/5);
+ button = get_action(CONTEXT_TREE,
+ list_do_action_timeout(&tree_lists, HZ/2));
oldbutton = button;
- need_update = gui_synclist_do_button(&tree_lists, &button,LIST_WRAP_UNLESS_HELD);
+ gui_synclist_do_button(&tree_lists, &button,LIST_WRAP_UNLESS_HELD);
tc.selected_item = gui_synclist_get_sel_pos(&tree_lists);
switch ( button ) {
case ACTION_STD_OK:
@@ -750,57 +814,6 @@ static int dirbrowse()
}
case ACTION_NONE:
- if (thumbnail_time != -1 &&
- TIME_AFTER(current_tick, thumbnail_time))
- { /* a delayed hovering thumbnail is due now */
- int res;
- int attr;
- char* name;
-
-#ifdef HAVE_TAGCACHE
- if (id3db)
- {
- attr = tagtree_get_attr(&tc);
- name = tagtree_get_entry(&tc, lasti)->name;
- }
- else
-#endif
- {
- attr = dircache[lasti].attr;
- name = dircache[lasti].name;
- }
-
- if (attr & ATTR_DIRECTORY)
- {
- DEBUGF("Playing directory thumbnail: %s", currdir);
- res = ft_play_dirname(name);
- if (res < 0) /* failed, not existing */
- {
- /* say the number or spell if required as a fallback */
- switch (global_settings.talk_dir)
- {
- case 1: /* dirs as numbers */
- talk_id(VOICE_DIR, false);
- talk_number(lasti+1, true);
- break;
-
- case 2: /* dirs spelled */
- talk_spell(name, false);
- break;
- }
- }
- }
- else
- {
- DEBUGF("Playing file thumbnail: %s/%s%s\n",
- currdir, name,
- file_thumbnail_ext);
- /* no fallback necessary, we knew in advance
- that the file exists */
- ft_play_filename(currdir, name);
- }
- thumbnail_time = -1; /* job done */
- }
gui_syncstatusbar_draw(&statusbars, false);
break;
@@ -872,87 +885,12 @@ static int dirbrowse()
if (restore || reload_dir) {
/* restore display */
numentries = update_dir();
+ reload_dir = false;
if (currdir[1] && (numentries < 0))
{ /* not in root and reload failed */
reload_root = true; /* try root */
- reload_dir = false;
goto check_rescan;
}
- need_update = true;
- reload_dir = false;
- }
-
- if(need_update) {
- need_update=false;
- if ( numentries > 0 ) {
- /* Voice the file if changed */
- if(lasti != tc.selected_item || restore) {
- int attr;
- char* name;
-
- lasti = tc.selected_item;
- thumbnail_time = -1; /* Cancel whatever we were
- about to say */
-
-#ifdef HAVE_TAGCACHE
- if (id3db)
- {
- attr = tagtree_get_attr(&tc);
- name = tagtree_get_entry(&tc, tc.selected_item)->name;
- }
- else
-#endif
- {
- attr = dircache[tc.selected_item].attr;
- name = dircache[tc.selected_item].name;
- }
-
- /* Directory? */
- if (attr & ATTR_DIRECTORY)
- {
- /* schedule thumbnail playback if required */
- if (global_settings.talk_dir_clip)
- thumbnail_time = current_tick + HOVER_DELAY;
- else
- {
- /* talk directly */
- switch (global_settings.talk_dir)
- {
- case 1: /* dirs as numbers */
- talk_id(VOICE_DIR, false);
- talk_number(tc.selected_item+1, true);
- break;
-
- case 2: /* dirs spelled */
- talk_spell(name, false);
- break;
- }
- }
- }
- else /* file */
- {
- /* schedule thumbnail playback if required */
- if (global_settings.talk_file_clip && (attr & FILE_ATTR_THUMBNAIL))
- thumbnail_time = current_tick + HOVER_DELAY;
- else
- {
- /* talk directly */
- switch (global_settings.talk_file)
- {
- case 1: /* files as numbers */
- ft_play_filenumber(
- tc.selected_item-tc.dirsindir+1,
- attr & FILE_ATTR_MASK);
- break;
-
- case 2: /* files spelled */
- talk_spell(name, false);
- break;
- }
- }
- }
- }
- }
}
}
return true;
@@ -1226,24 +1164,17 @@ void bookmark_play(char *resume_file, in
start_wps=true;
}
-static int ft_play_filenumber(int pos, int attr)
+static void say_filetype(int attr)
{
/* try to find a voice ID for the extension, if known */
int j;
- int ext_id = -1; /* default to none */
+ attr &= FILE_ATTR_MASK; /* file type */
for (j=0; jflags & F_BOOL_SETTING) == F_BOOL_SETTING)
{
bool val = temp_var==1?true:false;
@@ -167,6 +169,7 @@ static void option_talk(struct settings_
talk_id(P2ID(setting->choice_setting->desc[value]), false);
}
}
+ return 0;
}
#if 0
int option_select_next_val(struct settings_list *setting,
@@ -319,6 +322,8 @@ bool option_screen(struct settings_list
gui_synclist_set_title(&lists, title, Icon_Questionmark);
gui_synclist_set_icon_callback(&lists, NULL);
+ if(talk_menus_enabled())
+ gui_synclist_set_voice_callback(&lists, option_talk);
/* set the number of items and current selection */
if (var_type == F_T_INT || var_type == F_T_UINT)
@@ -375,13 +380,11 @@ bool option_screen(struct settings_list
gui_synclist_limit_scroll(&lists, true);
gui_synclist_draw(&lists);
/* talk the item */
- option_talk(setting, *variable);
+ gui_synclist_speak_item(&lists);
while (!done)
{
- action = get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
- if (action == ACTION_NONE)
- continue;
- if (gui_synclist_do_button(&lists, &action,
+ if (list_do_action(CONTEXT_LIST, TIMEOUT_BLOCK,
+ &lists, &action,
allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF))
{
selected = gui_synclist_get_sel_pos(&lists);
@@ -391,9 +394,9 @@ bool option_screen(struct settings_list
if (!use_temp_var)
*(bool*)setting->setting = selected==1?true:false;
}
- /* talk */
- option_talk(setting, *variable);
}
+ else if (action == ACTION_NONE)
+ continue;
else if (action == ACTION_STD_CANCEL)
{
bool show_cancel = false;
Index: trunk/apps/menu.c
===================================================================
--- trunk.orig/apps/menu.c
+++ trunk/apps/menu.c
@@ -65,6 +65,7 @@
static struct menu_item_ex *current_submenus_menu;
static int current_subitems[MAX_MENU_SUBITEMS];
static int current_subitems_count = 0;
+static int talk_menu_item(int selected_item, void *data);
static void get_menu_callback(const struct menu_item_ex *m,
menu_callback_type *menu_callback)
@@ -207,6 +208,8 @@ static void init_menu_lists(const struct
(void)icon;
gui_synclist_set_icon_callback(lists, NULL);
#endif
+ if(talk_menus_enabled())
+ gui_synclist_set_voice_callback(lists, talk_menu_item);
gui_synclist_set_nb_items(lists,current_subitems_count);
gui_synclist_limit_scroll(lists,true);
gui_synclist_select_item(lists, find_menu_selection(selected));
@@ -215,19 +218,17 @@ static void init_menu_lists(const struct
if (callback && menu_callback)
menu_callback(ACTION_ENTER_MENUITEM,menu);
gui_synclist_draw(lists);
+ gui_synclist_speak_item(lists);
}
-static void talk_menu_item(const struct menu_item_ex *menu,
- struct gui_synclist *lists)
+static int talk_menu_item(int selected_item, void *data)
{
+ const struct menu_item_ex *menu = (const struct menu_item_ex *)data;
int id = -1;
int type;
unsigned char *str;
- int sel;
+ int sel = get_menu_selection(selected_item, menu);
- if (talk_menus_enabled())
- {
- sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
{
type = menu->submenus[sel]->flags&MENU_TYPE_MASK;
@@ -271,7 +272,7 @@ static void talk_menu_item(const struct
talk_id(id,false);
}
}
- }
+ return 0;
}
#define MAX_OPTIONS 32
bool do_setting_from_menu(const struct menu_item_ex *temp)
@@ -307,7 +308,6 @@ int do_menu(const struct menu_item_ex *s
int stack_top = 0;
bool in_stringlist, done = false;
menu_callback_type menu_callback = NULL;
- bool talk_item = false;
if (start_menu == NULL)
menu = &main_menu_;
else menu = start_menu;
@@ -320,25 +320,18 @@ int do_menu(const struct menu_item_ex *s
init_menu_lists(menu,&lists,selected,true);
in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID);
- talk_menu_item(menu, &lists);
-
/* load the callback, and only reload it if menu changes */
get_menu_callback(menu, &menu_callback);
- gui_synclist_draw(&lists);
while (!done)
{
- talk_item = false;
redraw_lists = false;
gui_syncstatusbar_draw(&statusbars, true);
- action = get_action(CONTEXT_MAINMENU,HZ);
+ action = get_action(CONTEXT_MAINMENU,
+ list_do_action_timeout(&lists, HZ));
/* HZ so the status bar redraws corectly */
- if (action == ACTION_NONE)
- {
- continue;
- }
- if (menu_callback)
+ if (action != ACTION_NONE && menu_callback)
{
int old_action = action;
action = menu_callback(action, menu);
@@ -356,10 +349,9 @@ int do_menu(const struct menu_item_ex *s
}
if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
- {
- talk_menu_item(menu, &lists);
continue;
- }
+ if (action == ACTION_NONE)
+ continue;
#ifdef HAVE_RECORDING
if (action == ACTION_STD_REC)
@@ -411,7 +403,6 @@ int do_menu(const struct menu_item_ex *s
menu_stack_selected_item[stack_top], false);
/* new menu, so reload the callback */
get_menu_callback(menu, &menu_callback);
- talk_item = true;
}
else if (menu != &root_menu_)
{
@@ -453,13 +444,11 @@ int do_menu(const struct menu_item_ex *s
init_menu_lists(temp, &lists, 0, true);
redraw_lists = false; /* above does the redraw */
menu = temp;
- talk_item = true;
}
break;
case MT_FUNCTION_CALL:
{
int return_value;
- talk_item = true;
if (temp->flags&MENU_FUNC_USEPARAM)
return_value = temp->function->function_w_param(
temp->function->param);
@@ -483,7 +472,6 @@ int do_menu(const struct menu_item_ex *s
init_menu_lists(menu, &lists, selected, true);
redraw_lists = false; /* above does the redraw */
}
- talk_item = true;
break;
}
case MT_RETURN_ID:
@@ -500,7 +488,6 @@ int do_menu(const struct menu_item_ex *s
menu = temp;
init_menu_lists(menu,&lists,0,false);
redraw_lists = false; /* above does the redraw */
- talk_item = true;
in_stringlist = true;
}
break;
@@ -534,11 +521,12 @@ int do_menu(const struct menu_item_ex *s
ret = MENU_ATTACHED_USB;
done = true;
}
- if (talk_item && !done)
- talk_menu_item(menu, &lists);
- if (redraw_lists)
+ if (redraw_lists && !done)
+ {
gui_synclist_draw(&lists);
+ gui_synclist_speak_item(&lists);
+ }
}
if (start_selected)
{