From f6251e4256b48ad85f176fb4219b27b654e3b05e Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Tue, 16 Dec 2008 12:05:16 +0000 Subject: Accept FS#9646 by Christopher Williams which fixes a few radio preset bugs: * presets list does not scroll horizontally properly (due to the list_do_action() repeatedly timing out after 1 second) * when returning from the presets list to the main radio screen, the highlighted item in the list scrolls on main radio screen (if it's too wide for the screen, that is) * when adding a preset while in the presets list (with ACTION_FM_PRESET) the list is not updated with the new preset * when clearing presets (or deleting the last preset), the main screen still shows the same preset number * when deleting a preset, the current preset number doesn't change if it's past the end of the list (this is partially related to the previous issue) * the find_closest_preset() routine could be improved to actually find the closest frequency that is saved as a preset * inputting a preset name could be optimized in both time and space (especially in radio_add_preset()); also the length parameter to kbd_input() includes the null terminator, so I added one to those arguments git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19457 a1c6a512-1295-4272-9138-f99709370657 --- apps/recorder/radio.c | 76 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index dee38b5475..a6213abfb1 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -295,34 +295,54 @@ static int find_preset(int freq) return -1; } -/* Return the first preset encountered in the search direction with +/* Return the closest preset encountered in the search direction with wraparound. */ static int find_closest_preset(int freq, int direction) { int i; + int lowpreset = 0; + int highpreset = 0; + int closest = -1; if (direction == 0) /* direction == 0 isn't really used */ return 0; - for (i = 0; i < MAX_PRESETS; i++) + for (i = 0; i < num_presets; i++) { - int preset_frequency = presets[i].frequency; - - if (preset_frequency == freq) + int f = presets[i].frequency; + if (f == freq) return i; /* Exact match = stop */ - /* Stop when the preset frequency exeeds freq so that we can - pick the correct one based on direction */ - if (preset_frequency > freq) - break; + + /* remember the highest and lowest presets for wraparound */ + if (f < presets[lowpreset].frequency) + lowpreset = i; + if (f > presets[highpreset].frequency) + highpreset = i; + + /* find the closest preset in the given direction */ + if (direction > 0 && f > freq) + { + if (closest < 0 || f < presets[closest].frequency) + closest = i; + } + else if (direction < 0 && f < freq) + { + if (closest < 0 || f > presets[closest].frequency) + closest = i; + } } - /* wrap around depending on direction */ - if (i == 0 || i >= num_presets - 1) - i = direction < 0 ? num_presets - 1 : 0; - else if (direction < 0) - i--; /* use previous */ + if (closest < 0) + { + /* no presets in the given direction */ + /* wrap around depending on direction */ + if (direction < 0) + closest = highpreset; + else + closest = lowpreset; + } - return i; + return closest; } static void remember_frequency(void) @@ -762,6 +782,7 @@ int radio_screen(void) FOR_NB_SCREENS(i) { screens[i].set_viewport(&vp[i]); + screens[i].stop_scroll(); screens[i].clear_viewport(); screens[i].update_viewport(); screens[i].set_viewport(NULL); @@ -1158,24 +1179,24 @@ static int radio_add_preset(void) if(num_presets < MAX_PRESETS) { - memset(buf, 0, MAX_FMPRESET_LEN); + buf[0] = '\0'; - if (!kbd_input(buf, MAX_FMPRESET_LEN)) + if (!kbd_input(buf, MAX_FMPRESET_LEN + 1)) { struct fmstation * const fms = &presets[num_presets]; - buf[MAX_FMPRESET_LEN] = '\0'; strcpy(fms->name, buf); fms->frequency = curr_freq; num_presets++; presets_changed = true; presets_loaded = num_presets > 0; + return true; } } else { splash(HZ, ID2P(LANG_FM_NO_FREE_PRESETS)); } - return true; + return false; } /* needed to know which preset we are edit/delete-ing */ @@ -1188,11 +1209,10 @@ static int radio_edit_preset(void) { struct fmstation * const fms = &presets[selected_preset]; - strncpy(buf, fms->name, MAX_FMPRESET_LEN); + strcpy(buf, fms->name); - if (!kbd_input(buf, MAX_FMPRESET_LEN)) + if (!kbd_input(buf, MAX_FMPRESET_LEN + 1)) { - buf[MAX_FMPRESET_LEN] = '\0'; strcpy(fms->name, buf); presets_changed = true; } @@ -1213,6 +1233,8 @@ static int radio_delete_preset(void) memmove(fms, fms + 1, (uintptr_t)(fms + num_presets) - (uintptr_t)fms); + if (curr_preset >= num_presets) + --curr_preset; } /* Don't ask to save when all presets are deleted. */ @@ -1222,6 +1244,7 @@ static int radio_delete_preset(void) { /* The preset list will be cleared, switch to Scan Mode. */ radio_mode = RADIO_SCAN_MODE; + curr_preset = -1; presets_loaded = false; } @@ -1295,6 +1318,7 @@ static int clear_preset_list(void) presets_loaded = false; /* The preset list will be cleared switch to Scan Mode. */ radio_mode = RADIO_SCAN_MODE; + curr_preset = -1; presets_changed = false; /* Don't ask to save when clearing the list. */ @@ -1374,12 +1398,16 @@ static int handle_radio_presets(void) { gui_synclist_draw(&lists); gui_syncstatusbar_draw(&statusbars, true); - list_do_action(CONTEXT_STD, HZ, + list_do_action(CONTEXT_STD, TIMEOUT_BLOCK, &lists, &action, LIST_WRAP_UNLESS_HELD); switch (action) { case ACTION_STD_MENU: - radio_add_preset(); + if (radio_add_preset()) + { + gui_synclist_set_nb_items(&lists, num_presets); + gui_synclist_select_item(&lists, num_presets - 1); + } break; case ACTION_STD_CANCEL: result = 1; -- cgit v1.2.3