all repos — mgba @ 70231031630875a52521706deeb701c0605d4c37

mGBA Game Boy Advance Emulator

GUI: File select usability improvements
Jeffrey Pfau jeffrey@endrift.com
Sat, 29 Aug 2015 23:51:44 -0700
commit

70231031630875a52521706deeb701c0605d4c37

parent

7e74cba49a7ed6408897f3a946319899a43a3f12

M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -136,13 +136,15 @@ }

struct GUIParams params = { 320, 240, - font, _drawStart, _drawEnd, _pollInput + font, "/", _drawStart, _drawEnd, _pollInput, + + GUI_PARAMS_TRAIL }; + GUIInit(&params); - char currentPath[256] = ""; while (aptMainLoop()) { char path[256]; - if (!selectFile(&params, "/", path, currentPath, sizeof(path), GBAIsROM)) { + if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM)) { break; } _drawStart();
M src/platform/psp2/main.csrc/platform/psp2/main.c

@@ -65,13 +65,13 @@ struct GUIFont* font = GUIFontCreate();

GBAPSP2Setup(); struct GUIParams params = { PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS, - font, _drawStart, _drawEnd, _pollInput + font, "cache0:", _drawStart, _drawEnd, _pollInput }; + GUIInit(&params); - char currentPath[256] = ""; while (true) { char path[256]; - if (!selectFile(&params, "cache0:", path, currentPath, sizeof(path), GBAIsROM)) { + if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM)) { break; } if (!GBAPSP2LoadROM(path)) {
M src/platform/wii/main.csrc/platform/wii/main.c

@@ -165,18 +165,21 @@ blip_set_rates(context.gba->audio.left, GBA_ARM7TDMI_FREQUENCY, 48000);

blip_set_rates(context.gba->audio.right, GBA_ARM7TDMI_FREQUENCY, 48000); #endif - char currentPath[256] = ""; + struct GUIParams params = { + 352, 230, + font, "/", _drawStart, _drawEnd, _pollInput, + + GUI_PARAMS_TRAIL + }; + GUIInit(&params); + while (true) { char path[256]; guOrtho(proj, -20, 240, 0, 352, 0, 300); GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); - struct GUIParams params = { - 352, 230, - font, _drawStart, _drawEnd, _pollInput - }; - if (!selectFile(&params, "/", path, currentPath, sizeof(path), GBAIsROM) || !GBAWiiLoadGame(path)) { + if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM) || !GBAWiiLoadGame(path)) { break; } GBAContextStart(&context);
M src/util/gui.csrc/util/gui.c

@@ -5,6 +5,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gui.h" +void GUIInit(struct GUIParams* params) { + memset(params->inputHistory, 0, sizeof(params->inputHistory)); + strncpy(params->currentPath, params->basePath, PATH_MAX); +} + void GUIPollInput(struct GUIParams* params, int* newInputOut, int* heldInput) { int input = params->pollInput(); int newInput = 0;

@@ -25,3 +30,9 @@ if (heldInput) {

*heldInput = input; } } + +void GUIInvalidateKeys(struct GUIParams* params) { + for (int i = 0; i < GUI_INPUT_MAX; ++i) { + params->inputHistory[i] = 0; + } +}
M src/util/gui.hsrc/util/gui.h

@@ -8,7 +8,10 @@ #define GUI_H

#include "util/common.h" +#include "util/vector.h" + struct GUIFont; +DECLARE_VECTOR(FileList, char*); enum GUIInput { GUI_INPUT_NONE = -1,

@@ -28,6 +31,7 @@ struct GUIParams {

unsigned width; unsigned height; const struct GUIFont* font; + const char* basePath; void (*drawStart)(void); void (*drawEnd)(void);

@@ -35,8 +39,16 @@ int (*pollInput)(void);

// State int inputHistory[GUI_INPUT_MAX]; + + // Directories + char currentPath[PATH_MAX]; + size_t fileIndex; }; +#define GUI_PARAMS_TRAIL {}, "" + +void GUIInit(struct GUIParams* params); void GUIPollInput(struct GUIParams* params, int* newInput, int* heldInput); +void GUIInvalidateKeys(struct GUIParams* params); #endif
M src/util/gui/file-select.csrc/util/gui/file-select.c

@@ -6,12 +6,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "file-select.h" #include "util/gui/font.h" -#include "util/vector.h" #include "util/vfs.h" #include <stdlib.h> -DECLARE_VECTOR(FileList, char*); DEFINE_VECTOR(FileList, char*); #define ITERATION_SIZE 5

@@ -91,11 +89,7 @@ qsort(FileListGetPointer(currentFiles, 1), FileListSize(currentFiles) - 1, sizeof(char*), _strpcmp);

return true; } -bool selectFile(struct GUIParams* params, const char* basePath, char* outPath, char* currentPath, size_t outLen, bool (*filter)(struct VFile*)) { - if (!currentPath[0]) { - strncpy(currentPath, basePath, outLen); - } - size_t fileIndex = 0; +bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filter)(struct VFile*)) { size_t start = 0; size_t pageSize = params->height / GUIFontHeight(params->font); if (pageSize > 4) {

@@ -104,63 +98,66 @@ } else {

pageSize = 1; } + GUIInvalidateKeys(params); struct FileList currentFiles; FileListInit(&currentFiles, 0); - _refreshDirectory(params, currentPath, &currentFiles, filter); + _refreshDirectory(params, params->currentPath, &currentFiles, filter); while (true) { int newInput = 0; GUIPollInput(params, &newInput, 0); - if (newInput & (1 << GUI_INPUT_UP) && fileIndex > 0) { - --fileIndex; + if (newInput & (1 << GUI_INPUT_UP) && params->fileIndex > 0) { + --params->fileIndex; } - if (newInput & (1 << GUI_INPUT_DOWN) && fileIndex < FileListSize(&currentFiles) - 1) { - ++fileIndex; + if (newInput & (1 << GUI_INPUT_DOWN) && params->fileIndex < FileListSize(&currentFiles) - 1) { + ++params->fileIndex; } if (newInput & (1 << GUI_INPUT_LEFT)) { - if (fileIndex >= pageSize) { - fileIndex -= pageSize; + if (params->fileIndex >= pageSize) { + params->fileIndex -= pageSize; } else { - fileIndex = 0; + params->fileIndex = 0; } } if (newInput & (1 << GUI_INPUT_RIGHT)) { - if (fileIndex + pageSize < FileListSize(&currentFiles)) { - fileIndex += pageSize; + if (params->fileIndex + pageSize < FileListSize(&currentFiles)) { + params->fileIndex += pageSize; } else { - fileIndex = FileListSize(&currentFiles) - 1; + params->fileIndex = FileListSize(&currentFiles) - 1; } } - if (fileIndex < start) { - start = fileIndex; + if (params->fileIndex < start) { + start = params->fileIndex; } - while ((fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) { + while ((params->fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) { ++start; } if (newInput & (1 << GUI_INPUT_CANCEL)) { break; } if (newInput & (1 << GUI_INPUT_SELECT)) { - if (fileIndex == 0) { - _upDirectory(currentPath); - if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) { + if (params->fileIndex == 0) { + _upDirectory(params->currentPath); + if (!_refreshDirectory(params, params->currentPath, &currentFiles, filter)) { break; } } else { - size_t len = strlen(currentPath); + size_t len = strlen(params->currentPath); const char* sep = PATH_SEP; - if (currentPath[len - 1] == *sep) { + if (params->currentPath[len - 1] == *sep) { sep = ""; } - snprintf(outPath, outLen, "%s%s%s", currentPath, sep, *FileListGetPointer(&currentFiles, fileIndex)); - if (!_refreshDirectory(params, outPath, &currentFiles, filter)) { + snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, *FileListGetPointer(&currentFiles, params->fileIndex)); + + struct FileList newFiles; + FileListInit(&newFiles, 0); + if (!_refreshDirectory(params, outPath, &newFiles, filter)) { + _cleanFiles(&newFiles); + FileListDeinit(&newFiles); struct VFile* vf = VFileOpen(outPath, O_RDONLY); if (!vf) { - if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) { - break; - } continue; } if (!filter || filter(vf)) {

@@ -172,31 +169,34 @@ }

vf->close(vf); break; } else { - strncpy(currentPath, outPath, outLen); + _cleanFiles(&currentFiles); + FileListDeinit(&currentFiles); + currentFiles = newFiles; + strncpy(params->currentPath, outPath, PATH_MAX); } } - fileIndex = 0; + params->fileIndex = 0; } if (newInput & (1 << GUI_INPUT_BACK)) { - if (strncmp(currentPath, basePath, outLen) == 0) { + if (strncmp(params->currentPath, params->basePath, PATH_MAX) == 0) { break; } - _upDirectory(currentPath); - if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) { + _upDirectory(params->currentPath); + if (!_refreshDirectory(params, params->currentPath, &currentFiles, filter)) { break; } - fileIndex = 0; + params->fileIndex = 0; } params->drawStart(); unsigned y = GUIFontHeight(params->font); - GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", currentPath); + GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", params->currentPath); y += 2 * GUIFontHeight(params->font); size_t i; for (i = start; i < FileListSize(&currentFiles); ++i) { int color = 0xE0A0A0A0; char bullet = ' '; - if (i == fileIndex) { + if (i == params->fileIndex) { color = 0xFFFFFFFF; bullet = '>'; }
M src/util/gui/file-select.hsrc/util/gui/file-select.h

@@ -10,6 +10,6 @@ #include "util/gui.h"

struct VFile; -bool selectFile(struct GUIParams*, const char* basePath, char* outPath, char* currentPath, size_t outLen, bool (*filter)(struct VFile*)); +bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filter)(struct VFile*)); #endif