mirror of https://github.com/mgba-emu/mgba.git
mGUI: Revamp file filtering
This commit is contained in:
parent
cfc90a3b67
commit
cbf460a164
|
@ -14,7 +14,7 @@ CXX_GUARD_START
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -15,11 +15,25 @@
|
|||
#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 = {
|
||||
.title = "Configure",
|
||||
|
@ -183,7 +197,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
|
|||
}
|
||||
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 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
|
|||
#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;
|
||||
|
|
|
@ -73,6 +73,24 @@ static struct mGUILogger {
|
|||
.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 @@ void mGUIRunloop(struct mGUIRunner* runner) {
|
|||
}
|
||||
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);
|
||||
|
|
|
@ -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 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
|
|||
} 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 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
|
|||
}
|
||||
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;
|
||||
}
|
||||
++item;
|
||||
|
||||
if (failed) {
|
||||
free((char*) testItem->title);
|
||||
GUIMenuItemListShift(currentFiles, item, 1);
|
||||
} else {
|
||||
++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 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
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 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
|
||||
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 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue