From 448f1f629d8b01b48164ee0560d5596b8c5d9be0 Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Wed, 23 Jul 2025 02:33:30 -0400 Subject: [PATCH] Bumper l/r or -/+ -> prev/next letter in file picker (#1007) --- file_io.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ file_io.h | 2 ++ menu.cpp | 10 +++++++-- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/file_io.cpp b/file_io.cpp index da6f899..774a732 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -1838,6 +1838,65 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons if (iFirstEntry < 0) iFirstEntry = 0; } } + else if (mode == SCANF_NEXT_CHAR) + { + //DirItem is sorted, so just advance until the first character changes. + //if we reach the end before that don't change anything. + //If we change d_type also consider that 'next'. This means next + //advances through directories, and then advances through files + + int found = -1; + char curChar = toupper(DirItem[iSelectedEntry].altname[0]); + char curdType = DirItem[iSelectedEntry].de.d_type; + for (int i = iSelectedEntry+1; i < flist_nDirEntries(); i++) + { + if (toupper(DirItem[i].altname[0]) != curChar || DirItem[i].de.d_type != curdType) + { + found = i; + break; + } + } + + if (found >= 0) + { + iSelectedEntry = found; + if (iSelectedEntry + (OsdGetSize() / 2) >= flist_nDirEntries()) iFirstEntry = flist_nDirEntries() - OsdGetSize(); + else iFirstEntry = iSelectedEntry - (OsdGetSize()/2) + 1; + if (iFirstEntry < 0) iFirstEntry = 0; + } + } + else if (mode == SCANF_PREV_CHAR) + { + + //Previous seek seeks to the FIRST entry that starts with the previous letter + //Search backward until the first char changes, and then continue looking backward + //until it changes again. + int found = -1; + bool sawChange = false; + char curChar = toupper(DirItem[iSelectedEntry].altname[0]); + char curdType = DirItem[iSelectedEntry].de.d_type; + for (int i = iSelectedEntry-1; i >= 0; i--) + { + if (toupper(DirItem[i].altname[0]) != curChar || DirItem[i].de.d_type != curdType) + { + if (sawChange) + { + found = i+1; + break; + } + sawChange = true; + curChar = toupper(DirItem[i].altname[0]); + } + } + + if (found >= 0) + { + iSelectedEntry = found; + if (iSelectedEntry + (OsdGetSize() / 2) >= flist_nDirEntries()) iFirstEntry = flist_nDirEntries() - OsdGetSize(); + else iFirstEntry = iSelectedEntry - (OsdGetSize()/2) + 1; + if (iFirstEntry < 0) iFirstEntry = 0; + } + } else { //printf("dir scan for key: %x/%c\n", mode, mode); diff --git a/file_io.h b/file_io.h index 04a724e..e69cd61 100644 --- a/file_io.h +++ b/file_io.h @@ -63,6 +63,8 @@ char* flist_GetPrevNext(const char* base_path, const char* file, const char* ext #define SCANF_PREV_PAGE -2 // find previous 16 files in directory #define SCANF_SET_ITEM 3 // find exact item #define SCANF_END 4 // find last file in directory +#define SCANF_NEXT_CHAR 5 // find next letter/number +#define SCANF_PREV_CHAR -5 // find previous letter/number // options flags #define SCANO_DIR 0b000000001 // include subdirectories diff --git a/menu.cpp b/menu.cpp index ba4d739..aeeec61 100644 --- a/menu.cpp +++ b/menu.cpp @@ -514,7 +514,7 @@ static uint32_t menu_key_get(void) else if (CheckTimer(repeat)) { repeat = GetTimer(REPEATRATE); - if (GetASCIIKey(c1) || ((menustate == MENU_COMMON2) && (menusub == 17)) || ((menustate == MENU_SYSTEM2) && (menusub == 5))) + if (GetASCIIKey(c1) || menustate == MENU_FILE_SELECT2 || ((menustate == MENU_COMMON2) && (menusub == 17)) || ((menustate == MENU_SYSTEM2) && (menusub == 5))) { c = c1; hold_cnt++; @@ -1240,7 +1240,7 @@ void HandleUI(void) } } - if (menu || select || up || down || left || right || (helptext_idx_old != helptext_idx)) + if (menu || select || up || down || left || right || plus || minus || (helptext_idx_old != helptext_idx)) { helptext_idx_old = helptext_idx; if (helpstate) OsdWrite(OsdGetSize()-1, STD_EXIT, (menumask - ((1 << (menusub + 1)) - 1)) <= 0, 0); // Redraw the Exit line... @@ -5090,6 +5090,12 @@ void HandleUI(void) menustate = MENU_FILE_SELECT1; } + if (plus || minus) + { + ScanDirectory(selPath, plus ? SCANF_NEXT_CHAR : SCANF_PREV_CHAR, fs_pFileExt, fs_Options); + menustate = MENU_FILE_SELECT1; + } + { char i; if ((i = GetASCIIKey(c)) > 1)