GUI: File select usability improvements
Jeffrey Pfau jeffrey@endrift.com
Sat, 29 Aug 2015 23:51:44 -0700
7 files changed,
80 insertions(+),
52 deletions(-)
M
src/platform/3ds/main.c
→
src/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(¶ms); - char currentPath[256] = ""; while (aptMainLoop()) { char path[256]; - if (!selectFile(¶ms, "/", path, currentPath, sizeof(path), GBAIsROM)) { + if (!GUISelectFile(¶ms, path, sizeof(path), GBAIsROM)) { break; } _drawStart();
M
src/platform/psp2/main.c
→
src/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(¶ms); - char currentPath[256] = ""; while (true) { char path[256]; - if (!selectFile(¶ms, "cache0:", path, currentPath, sizeof(path), GBAIsROM)) { + if (!GUISelectFile(¶ms, path, sizeof(path), GBAIsROM)) { break; } if (!GBAPSP2LoadROM(path)) {
M
src/platform/wii/main.c
→
src/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(¶ms); + 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(¶ms, "/", path, currentPath, sizeof(path), GBAIsROM) || !GBAWiiLoadGame(path)) { + if (!GUISelectFile(¶ms, path, sizeof(path), GBAIsROM) || !GBAWiiLoadGame(path)) { break; } GBAContextStart(&context);
M
src/util/gui.c
→
src/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.h
→
src/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.c
→
src/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(¤tFiles, 0); - _refreshDirectory(params, currentPath, ¤tFiles, filter); + _refreshDirectory(params, params->currentPath, ¤tFiles, 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(¤tFiles) - 1) { - ++fileIndex; + if (newInput & (1 << GUI_INPUT_DOWN) && params->fileIndex < FileListSize(¤tFiles) - 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(¤tFiles)) { - fileIndex += pageSize; + if (params->fileIndex + pageSize < FileListSize(¤tFiles)) { + params->fileIndex += pageSize; } else { - fileIndex = FileListSize(¤tFiles) - 1; + params->fileIndex = FileListSize(¤tFiles) - 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, ¤tFiles, filter)) { + if (params->fileIndex == 0) { + _upDirectory(params->currentPath); + if (!_refreshDirectory(params, params->currentPath, ¤tFiles, 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(¤tFiles, fileIndex)); - if (!_refreshDirectory(params, outPath, ¤tFiles, filter)) { + snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, *FileListGetPointer(¤tFiles, 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, ¤tFiles, filter)) { - break; - } continue; } if (!filter || filter(vf)) {@@ -172,31 +169,34 @@ }
vf->close(vf); break; } else { - strncpy(currentPath, outPath, outLen); + _cleanFiles(¤tFiles); + FileListDeinit(¤tFiles); + 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, ¤tFiles, filter)) { + _upDirectory(params->currentPath); + if (!_refreshDirectory(params, params->currentPath, ¤tFiles, 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(¤tFiles); ++i) { int color = 0xE0A0A0A0; char bullet = ' '; - if (i == fileIndex) { + if (i == params->fileIndex) { color = 0xFFFFFFFF; bullet = '>'; }
M
src/util/gui/file-select.h
→
src/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