Wii: Add text cursor

This commit is contained in:
Vicki Pfau 2022-01-05 22:10:01 -08:00
parent f176c096b0
commit 9f0d184e4b
4 changed files with 59 additions and 9 deletions

View File

@ -96,6 +96,7 @@ enum GUIIcon {
GUI_ICON_BACKSPACE,
GUI_ICON_KBD_SHIFT,
GUI_ICON_CAPSLOCK,
GUI_ICON_TEXT_CURSOR,
GUI_ICON_MAX,
};
@ -127,6 +128,7 @@ enum GUI9SliceStyle {
unsigned GUIFontHeight(const struct GUIFont*);
unsigned GUIFontGlyphWidth(const struct GUIFont*, uint32_t glyph);
unsigned GUIFontSpanWidth(const struct GUIFont*, const char* text);
unsigned GUIFontSpanCountWidth(const struct GUIFont*, const char* text, size_t len);
void GUIFontIconMetrics(const struct GUIFont*, enum GUIIcon icon, unsigned* w, unsigned* h);
ATTRIBUTE_FORMAT(printf, 6, 7)

View File

@ -1117,17 +1117,35 @@ static const struct GUIKeyboard symbols = {
.width = 24
};
static void _backspace(char* string) {
static size_t _backspace(char* string, size_t position) {
size_t len = strlen(string);
if (len) {
string[len - 1] = '\0';
if (position == 0) {
return position;
}
size_t newPos = position - 1;
char byte = string[newPos];
if (byte & 0x80) { // In a UTF-8 character
while (newPos > 0) {
--newPos;
if ((string[newPos] & 0xC0) != 0x80) {
// Found beginning of UTF-8 character
break;
}
}
}
if (len == position) {
string[newPos] = '\0';
} else if (position > 0 && position < len) {
memmove(&string[newPos], &string[position], len + 1 - position);
}
return newPos;
}
enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
GUIInvalidateKeys(params);
int curX = 0;
int curY = 0;
size_t position = strlen(keyboard->result);
const struct GUIKey* curKey = NULL;
const struct GUIKeyboard* currentKbd = &qwertyLower;
const struct GUIKeyboard* prevKbd = currentKbd;
@ -1171,7 +1189,7 @@ enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
curKey = NULL;
}
if (newInput & (1 << GUI_INPUT_BACK)) {
_backspace(keyboard->result);
position = _backspace(keyboard->result, position);
}
if (newInput & (1 << GUI_INPUT_CANCEL)) {
return GUI_KEYBOARD_CANCEL;
@ -1225,15 +1243,28 @@ enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
if (newInput & (1 << GUI_INPUT_SELECT) && curKey) {
switch (curKey->function) {
case GUI_KEYFUNC_INPUT_DATA:
strncat(keyboard->result, curKey->data, keyboard->maxLen + 1);
case GUI_KEYFUNC_INPUT_DATA: {
size_t dataLen = strlen(curKey->data);
size_t followingLen = strlen(&keyboard->result[position]);
size_t copySize = followingLen;
if (position + copySize > keyboard->maxLen) {
copySize = keyboard->maxLen - position;
}
memmove(&keyboard->result[position + dataLen], &keyboard->result[position], copySize + 1);
copySize = dataLen;
if (position + copySize > keyboard->maxLen) {
copySize = keyboard->maxLen - position;
}
memcpy(&keyboard->result[position], curKey->data, copySize);
position += copySize;
if (tempKbd) {
tempKbd = false;
currentKbd = prevKbd;
}
break;
}
case GUI_KEYFUNC_BACKSPACE:
_backspace(keyboard->result);
position = _backspace(keyboard->result, position);
break;
case GUI_KEYFUNC_SHIFT_KB:
tempKbd = true;
@ -1256,6 +1287,16 @@ enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
return GUI_KEYBOARD_DONE;
case GUI_KEYFUNC_CANCEL:
return GUI_KEYBOARD_CANCEL;
case GUI_KEYFUNC_LEFT:
if (position > 0) {
--position;
}
break;
case GUI_KEYFUNC_RIGHT:
if (position < strlen(keyboard->result)) {
++position;
}
break;
}
}
@ -1264,7 +1305,9 @@ enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
inputSize = params->width / width - 2;
}
GUIFontDraw9Slice(params->font, (params->width - width * inputSize) / 2 - 8, height * 3, width * inputSize + 16, height + 8, 0xFFFFFFFF, GUI_9SLICE_EMPTY);
GUIFontPrint(params->font, (params->width - width * inputSize) / 2, height * 4 - 8, GUI_ALIGN_LEFT, 0xFFFFFFFF, keyboard->result);
GUIFontPrint(params->font, (params->width - width * inputSize) / 2 + 8, height * 4 - 8, GUI_ALIGN_LEFT, 0xFFFFFFFF, keyboard->result);
unsigned cursorWidth = GUIFontSpanCountWidth(params->font, keyboard->result, position);
GUIFontDrawIcon(params->font, (params->width - width * inputSize) / 2 + 8 + cursorWidth, height * 4 - 4, GUI_ALIGN_HCENTER | GUI_ALIGN_BOTTOM, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_TEXT_CURSOR);
GUIDrawBattery(params);
GUIDrawClock(params);

View File

@ -195,4 +195,5 @@ const struct GUIIconMetric defaultIconMetrics[] = {
[GUI_ICON_BACKSPACE] = { 82, 18, 12, 12 },
[GUI_ICON_KBD_SHIFT] = { 114, 18, 12, 12 },
[GUI_ICON_CAPSLOCK] = { 130, 18, 12, 12 },
[GUI_ICON_TEXT_CURSOR] = { 103, 16, 3, 16 },
};

View File

@ -8,8 +8,12 @@
#include <mgba-util/string.h>
unsigned GUIFontSpanWidth(const struct GUIFont* font, const char* text) {
unsigned width = 0;
size_t len = strlen(text);
return GUIFontSpanCountWidth(font, text, len);
}
unsigned GUIFontSpanCountWidth(const struct GUIFont* font, const char* text, size_t len) {
unsigned width = 0;
while (len) {
uint32_t c = utf8Char(&text, &len);
if (c == '\1') {