GUI: Upstream cross-platform GUI code

This commit is contained in:
Jeffrey Pfau 2015-08-22 23:20:21 -07:00
parent e9d4219d7b
commit 6ea0db2ccd
6 changed files with 202 additions and 0 deletions

View File

@ -28,6 +28,7 @@ file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
file(GLOB GBA_RR_SRC ${CMAKE_SOURCE_DIR}/src/gba/rr/*.c)
file(GLOB GBA_SV_SRC ${CMAKE_SOURCE_DIR}/src/gba/supervisor/*.c)
file(GLOB GUI_SRC ${CMAKE_SOURCE_DIR}/src/gui/*.c)
file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.[cSs])
file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/*.c)
file(GLOB SIO_SRC ${CMAKE_SOURCE_DIR}/src/gba/sio/lockstep.c)

BIN
res/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

35
src/util/gui.h Normal file
View File

@ -0,0 +1,35 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef GUI_H
#define GUI_H
#include "util/common.h"
struct GUIFont;
enum GUIInput {
GUI_INPUT_NONE = -1,
GUI_INPUT_SELECT = 0,
GUI_INPUT_BACK,
GUI_INPUT_CANCEL,
GUI_INPUT_UP,
GUI_INPUT_DOWN,
GUI_INPUT_LEFT,
GUI_INPUT_RIGHT,
};
struct GUIParams {
int width;
int height;
const struct GUIFont* font;
void (*drawStart)(void);
void (*drawEnd)(void);
int (*pollInput)(void);
};
#endif

128
src/util/gui/file-select.c Normal file
View File

@ -0,0 +1,128 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "file-select.h"
#include "util/gui/font.h"
#include "util/vector.h"
#include "util/vfs.h"
DECLARE_VECTOR(FileList, char*);
DEFINE_VECTOR(FileList, char*);
void _cleanFiles(struct FileList* currentFiles) {
size_t size = FileListSize(currentFiles);
size_t i;
for (i = 0; i < size; ++i) {
free(*FileListGetPointer(currentFiles, i));
}
FileListClear(currentFiles);
}
void _upDirectory(char* currentPath) {
char* end = strrchr(currentPath, '/');
if (!end) {
return;
}
end[0] = '\0';
if (end[1]) {
return;
}
// TODO: What if there was a trailing slash?
}
bool _refreshDirectory(const char* currentPath, struct FileList* currentFiles) {
_cleanFiles(currentFiles);
struct VDir* dir = VDirOpen(currentPath);
if (!dir) {
return false;
}
struct VDirEntry* de;
while ((de = dir->listNext(dir))) {
if (de->name(de)[0] == '.') {
continue;
}
*FileListAppend(currentFiles) = strdup(de->name(de));
}
dir->close(dir);
return true;
}
bool selectFile(const struct GUIParams* params, const char* basePath, char* outPath, size_t outLen, const char* suffix) {
char currentPath[256];
strncpy(currentPath, basePath, sizeof(currentPath));
int oldInput = -1;
size_t fileIndex = 0;
size_t start = 0;
struct FileList currentFiles;
FileListInit(&currentFiles, 0);
_refreshDirectory(currentPath, &currentFiles);
while (true) {
int input = params->pollInput();
int newInput = input & (oldInput ^ input);
oldInput = input;
if (newInput & (1 << GUI_INPUT_UP) && fileIndex > 0) {
--fileIndex;
}
if (newInput & (1 << GUI_INPUT_DOWN) && fileIndex < FileListSize(&currentFiles) - 1) {
++fileIndex;
}
if (fileIndex < start) {
start = fileIndex;
}
while ((fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) {
++start;
}
if (newInput & (1 << GUI_INPUT_CANCEL)) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
if (newInput & (1 << GUI_INPUT_SELECT)) {
snprintf(currentPath, sizeof(currentPath), "%s%c%s", currentPath, '/', *FileListGetPointer(&currentFiles, fileIndex));
if (!_refreshDirectory(currentPath, &currentFiles)) {
strncpy(outPath, currentPath, outLen);
return true;
}
fileIndex = 0;
}
if (newInput & (1 << GUI_INPUT_BACK)) {
if (strncmp(currentPath, basePath, sizeof(currentPath)) == 0) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
_upDirectory(currentPath);
_refreshDirectory(currentPath, &currentFiles);
fileIndex = 0;
}
params->drawStart();
int y = GUIFontHeight(params->font);
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, "Current directory: %s", currentPath);
y += 2 * GUIFontHeight(params->font);
size_t i;
for (i = start; i < FileListSize(&currentFiles); ++i) {
int color = 0xE0A0A0A0;
char bullet = ' ';
if (i == fileIndex) {
color = 0xFFFFFFFF;
bullet = '>';
}
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, *FileListGetPointer(&currentFiles, i));
y += GUIFontHeight(params->font);
if (y + GUIFontHeight(params->font) > params->height) {
break;
}
}
y += GUIFontHeight(params->font) * 2;
params->drawEnd();
}
}

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef GUI_FILE_CHOOSER_H
#define GUI_FILE_CHOOSER_H
#include "util/gui.h"
bool selectFile(const struct GUIParams*, const char* basePath, char* outPath, size_t outLen, const char* suffix);
#endif

25
src/util/gui/font.h Normal file
View File

@ -0,0 +1,25 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef GUI_FONT_H
#define GUI_FONT_H
#include "util/common.h"
struct GUIFont;
struct GUIFont* GUIFontCreate(void);
void GUIFontDestroy(struct GUIFont*);
enum GUITextAlignment {
GUI_TEXT_LEFT = 0,
GUI_TEXT_CENTER,
GUI_TEXT_RIGHT
};
int GUIFontHeight(const struct GUIFont*);
void GUIFontPrintf(const struct GUIFont*, int x, int y, enum GUITextAlignment, uint32_t color, const char* text, ...);
#endif