From 6bac0b2eebc91209d6872665cb508bc863715719 Mon Sep 17 00:00:00 2001 From: OskarSigvardsson Date: Thu, 2 Jul 2020 01:14:53 +0200 Subject: [PATCH] Implemented type-to-filter functionality in long game lists Previously, when you started typing the name of a game in the long list of games, it would jump to each successive letter you typed. So if you wanted to play "Crash Bandicoot" on the GBA, and you started typing "CRA" on the keyboard, the menu would first jump to C, then R, then A. This is almost certainly not what you want, and not standard UX for these kinds of long lists. This commit changes the behaviour to filter the list based on what you've typed. So if you type "CRA", it will only show games beginning with "CRA". If you wish to clear the filter, you can do so with backspace. Also: if you don't type for a little bit (currently 2000 ms), it will also clear the prefix the next time you start typing. The functionality is implemented using the "prefix" argument to ScanDirectory. --- menu.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/menu.cpp b/menu.cpp index b696c53..dc81a00 100644 --- a/menu.cpp +++ b/menu.cpp @@ -3992,6 +3992,10 @@ void HandleUI(void) if (flist_nDirEntries()) { + static char prefix[256]; + static unsigned long prefix_typing_timer = 0; + int prefix_len = strlen(prefix); + ScrollLongName(); // scrolls file name if longer than display line if (c == KEY_HOME) @@ -4019,6 +4023,17 @@ void HandleUI(void) menustate = MENU_FILE_SELECT1; } + if (c == KEY_BACKSPACE && prefix_len > 0) + { + memset(prefix, 0, 256); + prefix_typing_timer = 0; + + printf("Prefix is: %s\n", prefix); + ScanDirectory(selPath, SCANF_INIT, fs_pFileExt, fs_Options); + + menustate = MENU_FILE_SELECT1; + } + if (down) // scroll down one entry { ScanDirectory(selPath, SCANF_NEXT, fs_pFileExt, fs_Options); @@ -4035,14 +4050,37 @@ void HandleUI(void) int i; if ((i = GetASCIIKey(c)) > 1) { - // find an entry beginning with given character - ScanDirectory(selPath, i, fs_pFileExt, fs_Options); + if (CheckTimer(prefix_typing_timer)) + { + memset(prefix, 0, 256); + prefix[0] = (char)i; + + // You need both ScanDirectory calls here: the first + // call "clears" the prefix, the second one scrolls to + // the right place in the list + ScanDirectory(selPath, SCANF_INIT, fs_pFileExt, fs_Options); + ScanDirectory(selPath, i, fs_pFileExt, fs_Options); + } + else if (prefix_len < 255) + { + prefix[prefix_len] = (char)i; + + ScanDirectory(selPath, SCANF_INIT, fs_pFileExt, fs_Options, prefix); + } + + prefix_typing_timer = GetTimer(2000); + printf("Prefix is: %s\n", prefix); + menustate = MENU_FILE_SELECT1; } } if (select) { + memset(prefix, 0, 256); + prefix_typing_timer = 0; + printf("Prefix is: %s\n", prefix); + static char name[256]; char type = flist_SelectedItem()->de.d_type; memcpy(name, flist_SelectedItem()->de.d_name, sizeof(name));