all repos — mgba @ cbf460a164a105f8b6dc17802b42860aa893d364

mGBA Game Boy Advance Emulator

mGUI: Revamp file filtering
Vicki Pfau vi@endrift.com
Mon, 03 Sep 2018 17:54:40 -0700
commit

cbf460a164a105f8b6dc17802b42860aa893d364

parent

cfc90a3b67d42d6019ddd44742068af6df3f54c8

M include/mgba-util/gui/file-select.hinclude/mgba-util/gui/file-select.h

@@ -14,7 +14,7 @@ #include <mgba-util/gui.h>

struct VFile; -bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filter)(struct VFile*)); +bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)); CXX_GUARD_END
M src/feature/gui/gui-config.csrc/feature/gui/gui-config.c

@@ -15,10 +15,24 @@ #include <mgba/internal/gb/gb.h>

#endif #include <mgba-util/gui/file-select.h> #include <mgba-util/gui/menu.h> +#include <mgba-util/vfs.h> #ifndef GUI_MAX_INPUTS #define GUI_MAX_INPUTS 7 #endif + +static bool _biosNamed(const char* name) { + char ext[PATH_MAX + 1] = {}; + separatePath(name, NULL, NULL, ext); + + if (strnstr(name, "bios", PATH_MAX)) { + return true; + } + if (!strncmp(ext, "bin", PATH_MAX)) { + return true; + } + return false; +} void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra) { struct GUIMenu menu = {

@@ -183,7 +197,7 @@ continue;

} if (!strcmp(item->data, "gba.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), GBAIsBIOS)) { + if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), _biosNamed, GBAIsBIOS)) { gbaBiosPath[0] = '\0'; } continue;

@@ -191,21 +205,21 @@ }

#ifdef M_CORE_GB if (!strcmp(item->data, "gb.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), GBIsBIOS)) { + if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), _biosNamed, GBIsBIOS)) { gbBiosPath[0] = '\0'; } continue; } if (!strcmp(item->data, "gbc.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), GBIsBIOS)) { + if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), _biosNamed, GBIsBIOS)) { gbcBiosPath[0] = '\0'; } continue; } if (!strcmp(item->data, "sgb.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), GBIsBIOS)) { + if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), _biosNamed, GBIsBIOS)) { sgbBiosPath[0] = '\0'; } continue;
M src/feature/gui/gui-runner.csrc/feature/gui/gui-runner.c

@@ -73,6 +73,24 @@ .vf = NULL,

.logLevel = 0 }; +static bool _testExtensions(const char* name) { + char ext[PATH_MAX] = {}; + separatePath(name, NULL, NULL, ext); + + if (!strncmp(ext, "sav", PATH_MAX)) { + return false; + } + if (!strncmp(ext, "png", PATH_MAX)) { + return false; + } + if (!strncmp(ext, "ini", PATH_MAX)) { + return false; + } + if (!strncmp(ext, "ss", 2)) { + return false; + } +} + static void _drawBackground(struct GUIBackground* background, void* context) { UNUSED(context); struct mGUIBackground* gbaBackground = (struct mGUIBackground*) background;

@@ -580,7 +598,7 @@ }

} while (true) { char path[PATH_MAX]; - if (!GUISelectFile(&runner->params, path, sizeof(path), 0)) { + if (!GUISelectFile(&runner->params, path, sizeof(path), _testExtensions, NULL)) { break; } mCoreConfigSetValue(&runner->config, "lastDirectory", runner->params.currentPath);
M src/util/gui/file-select.csrc/util/gui/file-select.c

@@ -47,7 +47,7 @@ static int _strpcmp(const void* a, const void* b) {

return strcasecmp(((const struct GUIMenuItem*) a)->title, ((const struct GUIMenuItem*) b)->title); } -static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, struct GUIMenuItemList* currentFiles, bool (*filter)(struct VFile*)) { +static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, struct GUIMenuItemList* currentFiles, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)) { _cleanFiles(currentFiles); struct VDir* dir = VDirOpen(currentPath);

@@ -90,7 +90,7 @@ name = n2;

} else { name = strdup(name); } - *GUIMenuItemListAppend(currentFiles) = (struct GUIMenuItem) { .title = name }; + *GUIMenuItemListAppend(currentFiles) = (struct GUIMenuItem) { .title = name, .data = (void*) de->type(de) }; ++items; } qsort(GUIMenuItemListGetPointer(currentFiles, 1), GUIMenuItemListSize(currentFiles) - 1, sizeof(struct GUIMenuItem), _strpcmp);

@@ -116,42 +116,48 @@ params->guiFinish();

} params->drawEnd(); } - if (!filter) { + struct GUIMenuItem* testItem = GUIMenuItemListGetPointer(currentFiles, item); + if (testItem->data != (void*) VFS_FILE) { ++item; continue; } - struct VDir* vd = dir->openDir(dir, GUIMenuItemListGetPointer(currentFiles, item)->title); - if (vd) { - vd->close(vd); - ++item; - continue; + bool failed = false; + if (filterName && !filterName(testItem->title)) { + failed = true; } - struct VFile* vf = dir->openFile(dir, GUIMenuItemListGetPointer(currentFiles, item)->title, O_RDONLY); - if (vf) { - if (filter(vf)) { - ++item; + + if (!failed && filterContents) { + struct VFile* vf = dir->openFile(dir, testItem->title, O_RDONLY); + if (!vf) { + failed = true; } else { - free((char*) GUIMenuItemListGetPointer(currentFiles, item)->title); - GUIMenuItemListShift(currentFiles, item, 1); + if (!filterContents(vf)) { + failed = true; + } + vf->close(vf); } - vf->close(vf); - continue; + } + + if (failed) { + free((char*) testItem->title); + GUIMenuItemListShift(currentFiles, item, 1); + } else { + ++item; } - ++item; } dir->close(dir); return true; } -bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filter)(struct VFile*)) { +bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)) { struct GUIMenu menu = { .title = "Select file", .subtitle = params->currentPath, .index = params->fileIndex, }; GUIMenuItemListInit(&menu.items, 0); - _refreshDirectory(params, params->currentPath, &menu.items, filter); + _refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents); while (true) { struct GUIMenuItem* item;

@@ -163,7 +169,7 @@ }

if (reason == GUI_MENU_EXIT_ACCEPT) { if (params->fileIndex == 0) { _upDirectory(params->currentPath); - if (!_refreshDirectory(params, params->currentPath, &menu.items, filter)) { + if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents)) { break; } } else {

@@ -176,7 +182,7 @@ snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, item->title);

struct GUIMenuItemList newFiles; GUIMenuItemListInit(&newFiles, 0); - if (!_refreshDirectory(params, outPath, &newFiles, filter)) { + if (!_refreshDirectory(params, outPath, &newFiles, filterName, filterContents)) { _cleanFiles(&newFiles); GUIMenuItemListDeinit(&newFiles); _cleanFiles(&menu.items);

@@ -197,7 +203,7 @@ if (strncmp(params->currentPath, params->basePath, PATH_MAX) == 0) {

break; } _upDirectory(params->currentPath); - if (!_refreshDirectory(params, params->currentPath, &menu.items, filter)) { + if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents)) { break; } params->fileIndex = 0;