GUI: File select usability improvements

This commit is contained in:
Jeffrey Pfau 2015-08-29 23:51:44 -07:00
parent 7e74cba49a
commit 7023103163
7 changed files with 81 additions and 53 deletions

View File

@ -136,13 +136,15 @@ int main() {
struct GUIParams params = { struct GUIParams params = {
320, 240, 320, 240,
font, _drawStart, _drawEnd, _pollInput font, "/", _drawStart, _drawEnd, _pollInput,
};
GUI_PARAMS_TRAIL
};
GUIInit(&params);
char currentPath[256] = "";
while (aptMainLoop()) { while (aptMainLoop()) {
char path[256]; char path[256];
if (!selectFile(&params, "/", path, currentPath, sizeof(path), GBAIsROM)) { if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM)) {
break; break;
} }
_drawStart(); _drawStart();

View File

@ -65,13 +65,13 @@ int main() {
GBAPSP2Setup(); GBAPSP2Setup();
struct GUIParams params = { struct GUIParams params = {
PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS, PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
font, _drawStart, _drawEnd, _pollInput font, "cache0:", _drawStart, _drawEnd, _pollInput
}; };
GUIInit(&params);
char currentPath[256] = "";
while (true) { while (true) {
char path[256]; char path[256];
if (!selectFile(&params, "cache0:", path, currentPath, sizeof(path), GBAIsROM)) { if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM)) {
break; break;
} }
if (!GBAPSP2LoadROM(path)) { if (!GBAPSP2LoadROM(path)) {

View File

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

View File

@ -5,6 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gui.h" #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) { void GUIPollInput(struct GUIParams* params, int* newInputOut, int* heldInput) {
int input = params->pollInput(); int input = params->pollInput();
int newInput = 0; int newInput = 0;
@ -25,3 +30,9 @@ void GUIPollInput(struct GUIParams* params, int* newInputOut, int* heldInput) {
*heldInput = input; *heldInput = input;
} }
} }
void GUIInvalidateKeys(struct GUIParams* params) {
for (int i = 0; i < GUI_INPUT_MAX; ++i) {
params->inputHistory[i] = 0;
}
}

View File

@ -8,7 +8,10 @@
#include "util/common.h" #include "util/common.h"
#include "util/vector.h"
struct GUIFont; struct GUIFont;
DECLARE_VECTOR(FileList, char*);
enum GUIInput { enum GUIInput {
GUI_INPUT_NONE = -1, GUI_INPUT_NONE = -1,
@ -28,6 +31,7 @@ struct GUIParams {
unsigned width; unsigned width;
unsigned height; unsigned height;
const struct GUIFont* font; const struct GUIFont* font;
const char* basePath;
void (*drawStart)(void); void (*drawStart)(void);
void (*drawEnd)(void); void (*drawEnd)(void);
@ -35,8 +39,16 @@ struct GUIParams {
// State // State
int inputHistory[GUI_INPUT_MAX]; 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 GUIPollInput(struct GUIParams* params, int* newInput, int* heldInput);
void GUIInvalidateKeys(struct GUIParams* params);
#endif #endif

View File

@ -6,12 +6,10 @@
#include "file-select.h" #include "file-select.h"
#include "util/gui/font.h" #include "util/gui/font.h"
#include "util/vector.h"
#include "util/vfs.h" #include "util/vfs.h"
#include <stdlib.h> #include <stdlib.h>
DECLARE_VECTOR(FileList, char*);
DEFINE_VECTOR(FileList, char*); DEFINE_VECTOR(FileList, char*);
#define ITERATION_SIZE 5 #define ITERATION_SIZE 5
@ -91,11 +89,7 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
return true; return true;
} }
bool selectFile(struct GUIParams* params, const char* basePath, char* outPath, char* currentPath, size_t outLen, bool (*filter)(struct VFile*)) { bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filter)(struct VFile*)) {
if (!currentPath[0]) {
strncpy(currentPath, basePath, outLen);
}
size_t fileIndex = 0;
size_t start = 0; size_t start = 0;
size_t pageSize = params->height / GUIFontHeight(params->font); size_t pageSize = params->height / GUIFontHeight(params->font);
if (pageSize > 4) { if (pageSize > 4) {
@ -104,63 +98,66 @@ bool selectFile(struct GUIParams* params, const char* basePath, char* outPath, c
pageSize = 1; pageSize = 1;
} }
GUIInvalidateKeys(params);
struct FileList currentFiles; struct FileList currentFiles;
FileListInit(&currentFiles, 0); FileListInit(&currentFiles, 0);
_refreshDirectory(params, currentPath, &currentFiles, filter); _refreshDirectory(params, params->currentPath, &currentFiles, filter);
while (true) { while (true) {
int newInput = 0; int newInput = 0;
GUIPollInput(params, &newInput, 0); GUIPollInput(params, &newInput, 0);
if (newInput & (1 << GUI_INPUT_UP) && fileIndex > 0) { if (newInput & (1 << GUI_INPUT_UP) && params->fileIndex > 0) {
--fileIndex; --params->fileIndex;
} }
if (newInput & (1 << GUI_INPUT_DOWN) && fileIndex < FileListSize(&currentFiles) - 1) { if (newInput & (1 << GUI_INPUT_DOWN) && params->fileIndex < FileListSize(&currentFiles) - 1) {
++fileIndex; ++params->fileIndex;
} }
if (newInput & (1 << GUI_INPUT_LEFT)) { if (newInput & (1 << GUI_INPUT_LEFT)) {
if (fileIndex >= pageSize) { if (params->fileIndex >= pageSize) {
fileIndex -= pageSize; params->fileIndex -= pageSize;
} else { } else {
fileIndex = 0; params->fileIndex = 0;
} }
} }
if (newInput & (1 << GUI_INPUT_RIGHT)) { if (newInput & (1 << GUI_INPUT_RIGHT)) {
if (fileIndex + pageSize < FileListSize(&currentFiles)) { if (params->fileIndex + pageSize < FileListSize(&currentFiles)) {
fileIndex += pageSize; params->fileIndex += pageSize;
} else { } else {
fileIndex = FileListSize(&currentFiles) - 1; params->fileIndex = FileListSize(&currentFiles) - 1;
} }
} }
if (fileIndex < start) { if (params->fileIndex < start) {
start = fileIndex; start = params->fileIndex;
} }
while ((fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) { while ((params->fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) {
++start; ++start;
} }
if (newInput & (1 << GUI_INPUT_CANCEL)) { if (newInput & (1 << GUI_INPUT_CANCEL)) {
break; break;
} }
if (newInput & (1 << GUI_INPUT_SELECT)) { if (newInput & (1 << GUI_INPUT_SELECT)) {
if (fileIndex == 0) { if (params->fileIndex == 0) {
_upDirectory(currentPath); _upDirectory(params->currentPath);
if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) { if (!_refreshDirectory(params, params->currentPath, &currentFiles, filter)) {
break; break;
} }
} else { } else {
size_t len = strlen(currentPath); size_t len = strlen(params->currentPath);
const char* sep = PATH_SEP; const char* sep = PATH_SEP;
if (currentPath[len - 1] == *sep) { if (params->currentPath[len - 1] == *sep) {
sep = ""; sep = "";
} }
snprintf(outPath, outLen, "%s%s%s", currentPath, sep, *FileListGetPointer(&currentFiles, fileIndex)); snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, *FileListGetPointer(&currentFiles, params->fileIndex));
if (!_refreshDirectory(params, outPath, &currentFiles, filter)) {
struct FileList newFiles;
FileListInit(&newFiles, 0);
if (!_refreshDirectory(params, outPath, &newFiles, filter)) {
_cleanFiles(&newFiles);
FileListDeinit(&newFiles);
struct VFile* vf = VFileOpen(outPath, O_RDONLY); struct VFile* vf = VFileOpen(outPath, O_RDONLY);
if (!vf) { if (!vf) {
if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) {
break;
}
continue; continue;
} }
if (!filter || filter(vf)) { if (!filter || filter(vf)) {
@ -172,31 +169,34 @@ bool selectFile(struct GUIParams* params, const char* basePath, char* outPath, c
vf->close(vf); vf->close(vf);
break; break;
} else { } 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 (newInput & (1 << GUI_INPUT_BACK)) {
if (strncmp(currentPath, basePath, outLen) == 0) { if (strncmp(params->currentPath, params->basePath, PATH_MAX) == 0) {
break; break;
} }
_upDirectory(currentPath); _upDirectory(params->currentPath);
if (!_refreshDirectory(params, currentPath, &currentFiles, filter)) { if (!_refreshDirectory(params, params->currentPath, &currentFiles, filter)) {
break; break;
} }
fileIndex = 0; params->fileIndex = 0;
} }
params->drawStart(); params->drawStart();
unsigned y = GUIFontHeight(params->font); 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); y += 2 * GUIFontHeight(params->font);
size_t i; size_t i;
for (i = start; i < FileListSize(&currentFiles); ++i) { for (i = start; i < FileListSize(&currentFiles); ++i) {
int color = 0xE0A0A0A0; int color = 0xE0A0A0A0;
char bullet = ' '; char bullet = ' ';
if (i == fileIndex) { if (i == params->fileIndex) {
color = 0xFFFFFFFF; color = 0xFFFFFFFF;
bullet = '>'; bullet = '>';
} }

View File

@ -10,6 +10,6 @@
struct VFile; 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 #endif