GUI: Header with time and battery level

This commit is contained in:
Jeffrey Pfau 2015-09-19 00:32:49 -07:00
parent 91fb4407b9
commit c3aededf05
8 changed files with 135 additions and 41 deletions

View File

@ -85,6 +85,21 @@ static void _drawEnd(void) {
gspWaitForEvent(GSPEVENT_VBlank0, false);
}
static int _batteryState(void) {
u8 charge;
u8 adapter;
PTMU_GetBatteryLevel(0, &charge);
PTMU_GetBatteryChargeState(0, &adapter);
int state = 0;
if (adapter) {
state |= BATTERY_CHARGING;
}
if (charge > 0) {
--charge;
}
return state | charge;
}
static void _guiPrepare(void) {
guiDrawn = GUI_ACTIVE | GUI_THIS_FRAME;
int screen = screenMode < SM_PA_TOP ? GFX_BOTTOM : GFX_TOP;
@ -385,6 +400,7 @@ static void _postAudioBuffer(struct GBAAVStream* stream, struct GBAAudio* audio)
}
int main() {
ptmInit();
hasSound = !csndInit();
rotation.d.sample = _sampleRotation;
@ -444,12 +460,13 @@ int main() {
font, "/",
_drawStart, _drawEnd,
_pollInput, _pollCursor,
_batteryState,
_guiPrepare, _guiFinish,
GUI_PARAMS_TRAIL
},
.configExtra = (struct GUIMenuItem[]) {
{
{
.title = "Screen mode",
.data = "screenMode",
.submenu = 0,
@ -496,5 +513,6 @@ cleanup:
linearFree(audioRight);
}
csndExit();
ptmExit();
return 0;
}

View File

@ -85,6 +85,7 @@ int main() {
PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
font, "cache0:", _drawStart, _drawEnd,
_pollInput, _pollCursor,
0,
0, 0,
GUI_PARAMS_TRAIL

View File

@ -158,6 +158,7 @@ int main() {
font, "/",
_drawStart, _drawEnd,
_pollInput, _pollCursor,
0,
_guiPrepare, _guiFinish,
GUI_PARAMS_TRAIL

View File

@ -30,40 +30,3 @@ void GUIPollInput(struct GUIParams* params, uint32_t* newInputOut, uint32_t* hel
*heldInput = input;
}
}
enum GUICursorState GUIPollCursor(struct GUIParams* params, int* x, int* y) {
if (!params->pollCursor) {
return GUI_CURSOR_NOT_PRESENT;
}
enum GUICursorState state = params->pollCursor(x, y);
if (params->cursorState == GUI_CURSOR_DOWN) {
int dragX = *x - params->cx;
int dragY = *y - params->cy;
if (dragX * dragX + dragY * dragY > 25) {
params->cursorState = GUI_CURSOR_DRAGGING;
return GUI_CURSOR_DRAGGING;
}
if (state == GUI_CURSOR_UP || state == GUI_CURSOR_NOT_PRESENT) {
params->cursorState = GUI_CURSOR_UP;
return GUI_CURSOR_CLICKED;
}
} else {
params->cx = *x;
params->cy = *y;
}
if (params->cursorState == GUI_CURSOR_DRAGGING) {
if (state == GUI_CURSOR_UP || state == GUI_CURSOR_NOT_PRESENT) {
params->cursorState = GUI_CURSOR_UP;
return GUI_CURSOR_UP;
}
return GUI_CURSOR_DRAGGING;
}
params->cursorState = state;
return params->cursorState;
}
void GUIInvalidateKeys(struct GUIParams* params) {
for (int i = 0; i < GUI_INPUT_MAX; ++i) {
params->inputHistory[i] = 0;
}
}

View File

@ -36,6 +36,16 @@ enum GUICursorState {
GUI_CURSOR_DRAGGING
};
enum {
BATTERY_EMPTY = 0,
BATTERY_LOW = 1,
BATTERY_HALF = 2,
BATTERY_HIGH = 3,
BATTERY_FULL = 4,
BATTERY_CHARGING = 8
};
struct GUIBackground {
void (*draw)(struct GUIBackground*, void* context);
};
@ -50,6 +60,7 @@ struct GUIParams {
void (*drawEnd)(void);
uint32_t (*pollInput)(void);
enum GUICursorState (*pollCursor)(int* x, int* y);
int (*batteryState)(void);
void (*guiPrepare)(void);
void (*guiFinish)(void);

View File

@ -103,8 +103,8 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
if (params->guiPrepare) {
params->guiPrepare();
}
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", currentPath);
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, "(scanning item %zu of %zu)", i, items);
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_TEXT_LEFT, 0xFFFFFFFF, "(scanning item %zu of %zu)", i, items);
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", currentPath);
if (params->guiFinish) {
params->guiFinish();
}
@ -130,7 +130,8 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filter)(struct VFile*)) {
struct GUIMenu menu = {
.title = params->currentPath,
.title = "Select file",
.subtitle = params->currentPath,
.index = params->fileIndex,
};
GUIMenuItemListInit(&menu.items, 0);

View File

@ -106,6 +106,9 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
}
unsigned y = lineHeight;
GUIFontPrint(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->title);
if (menu->subtitle) {
GUIFontPrint(params->font, 0, y * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->subtitle);
}
y += 2 * lineHeight;
size_t i;
for (i = start; i < GUIMenuItemListSize(&menu->items); ++i) {
@ -125,6 +128,10 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
break;
}
}
GUIDrawBattery(params);
GUIDrawClock(params);
if (params->guiFinish) {
params->guiFinish();
}
@ -132,3 +139,91 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
}
return GUI_MENU_EXIT_CANCEL;
}
enum GUICursorState GUIPollCursor(struct GUIParams* params, int* x, int* y) {
if (!params->pollCursor) {
return GUI_CURSOR_NOT_PRESENT;
}
enum GUICursorState state = params->pollCursor(x, y);
if (params->cursorState == GUI_CURSOR_DOWN) {
int dragX = *x - params->cx;
int dragY = *y - params->cy;
if (dragX * dragX + dragY * dragY > 25) {
params->cursorState = GUI_CURSOR_DRAGGING;
return GUI_CURSOR_DRAGGING;
}
if (state == GUI_CURSOR_UP || state == GUI_CURSOR_NOT_PRESENT) {
params->cursorState = GUI_CURSOR_UP;
return GUI_CURSOR_CLICKED;
}
} else {
params->cx = *x;
params->cy = *y;
}
if (params->cursorState == GUI_CURSOR_DRAGGING) {
if (state == GUI_CURSOR_UP || state == GUI_CURSOR_NOT_PRESENT) {
params->cursorState = GUI_CURSOR_UP;
return GUI_CURSOR_UP;
}
return GUI_CURSOR_DRAGGING;
}
params->cursorState = state;
return params->cursorState;
}
void GUIInvalidateKeys(struct GUIParams* params) {
for (int i = 0; i < GUI_INPUT_MAX; ++i) {
params->inputHistory[i] = 0;
}
}
void GUIDrawBattery(struct GUIParams* params) {
if (!params->batteryState) {
return;
}
int state = params->batteryState();
uint32_t color = 0xFF000000;
if (state == (BATTERY_CHARGING | BATTERY_FULL)) {
color |= 0x2020FF;
} else if (state & BATTERY_CHARGING) {
color |= 0x20FF20;
} else if (state >= BATTERY_HALF) {
color |= 0xFFFFFF;
} else if (state == BATTERY_LOW) {
color |= 0x20FFFF;
} else {
color |= 0xFF2020;
}
const char* batteryText;
switch (state & ~BATTERY_CHARGING) {
case BATTERY_EMPTY:
batteryText = "[ ]";
break;
case BATTERY_LOW:
batteryText = "[I ]";
break;
case BATTERY_HALF:
batteryText = "[II ]";
break;
case BATTERY_HIGH:
batteryText = "[III ]";
break;
case BATTERY_FULL:
batteryText = "[IIII]";
break;
default:
batteryText = "[????]";
break;
}
GUIFontPrint(params->font, params->width, GUIFontHeight(params->font), GUI_TEXT_RIGHT, color, batteryText);
}
void GUIDrawClock(struct GUIParams* params) {
char buffer[32];
time_t t = time(0);
struct tm* tm = localtime(&t);
strftime(buffer, sizeof(buffer), "%H:%M:%S", tm);
GUIFontPrint(params->font, params->width / 2, GUIFontHeight(params->font), GUI_TEXT_CENTER, 0xFFFFFFFF, buffer);
}

View File

@ -22,6 +22,7 @@ DECLARE_VECTOR(GUIMenuItemList, struct GUIMenuItem);
struct GUIBackground;
struct GUIMenu {
const char* title;
const char* subtitle;
struct GUIMenuItemList items;
size_t index;
struct GUIBackground* background;
@ -36,4 +37,7 @@ enum GUIMenuExitReason {
struct GUIParams;
enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem** item);
void GUIDrawBattery(struct GUIParams* params);
void GUIDrawClock(struct GUIParams* params);
#endif