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.
This commit is contained in:
OskarSigvardsson
2020-07-02 01:14:53 +02:00
committed by GitHub
parent e1f2c7879e
commit 6bac0b2eeb

View File

@@ -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));