mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Fix multibyte letters in keyboard and input prompt
This commit is contained in:
parent
0275a85121
commit
830479f50c
@ -119,34 +119,50 @@ static void DrawKeyBoard(TouchBox* swkbd, const u32 uppercase) {
|
||||
}
|
||||
|
||||
static void DrawTextBox(const TouchBox* txtbox, const char* inputstr, const u32 cursor, u32* scroll) {
|
||||
const u32 input_shown = (txtbox->w / FONT_WIDTH_EXT) - 2;
|
||||
const u32 input_shown_length = (txtbox->w / FONT_WIDTH_EXT) - 2;
|
||||
const u32 inputstr_size = strlen(inputstr); // we rely on a zero terminated string
|
||||
const u16 x = txtbox->x;
|
||||
const u16 y = txtbox->y;
|
||||
|
||||
// fix scroll
|
||||
if (cursor < *scroll) *scroll = cursor;
|
||||
else if (cursor - *scroll > input_shown) *scroll = cursor - input_shown;
|
||||
if (cursor < *scroll) {
|
||||
*scroll = cursor;
|
||||
} else {
|
||||
int scroll_adjust = -input_shown_length;
|
||||
for (u32 i = *scroll; i < cursor; i++) {
|
||||
if (i >= inputstr_size || (inputstr[i] & 0xC0) != 0x80) scroll_adjust++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < scroll_adjust; i++)
|
||||
*scroll += *scroll >= inputstr_size ? 1 : GetCharSize(inputstr + *scroll);
|
||||
}
|
||||
|
||||
u32 input_shown_size = 0;
|
||||
for (u32 i = 0; i < input_shown_length || (*scroll + input_shown_size < inputstr_size && (inputstr[*scroll + input_shown_size] & 0xC0) == 0x80); input_shown_size++) {
|
||||
if (*scroll + input_shown_size >= inputstr_size || (inputstr[*scroll + input_shown_size] & 0xC0) != 0x80) i++;
|
||||
}
|
||||
|
||||
// draw input string
|
||||
DrawStringF(BOT_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%-*.*s%c",
|
||||
DrawStringF(BOT_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c",
|
||||
(*scroll) ? '<' : '|',
|
||||
(inputstr_size > input_shown) ? input_shown : inputstr_size,
|
||||
(inputstr_size > input_shown) ? input_shown : inputstr_size,
|
||||
input_shown_size,
|
||||
input_shown_size,
|
||||
(*scroll > inputstr_size) ? "" : inputstr + *scroll,
|
||||
(inputstr_size > input_shown) ? 0 : input_shown - inputstr_size,
|
||||
(inputstr_size > input_shown) ? 0 : input_shown - inputstr_size,
|
||||
"",
|
||||
(inputstr_size - (s32) *scroll > input_shown) ? '>' : '|'
|
||||
(inputstr_size - (s32) *scroll > input_shown_size) ? '>' : '|'
|
||||
);
|
||||
|
||||
// draw cursor
|
||||
u16 cpos = 0;
|
||||
for (u16 i = *scroll; i < cursor; i++) {
|
||||
if (i >= inputstr_size || (inputstr[i] & 0xC0) != 0x80) cpos++;
|
||||
}
|
||||
|
||||
DrawStringF(BOT_SCREEN, x-(FONT_WIDTH_EXT/2), y+10, COLOR_STD_FONT, COLOR_STD_BG, "%-*.*s^%-*.*s",
|
||||
1 + cursor - *scroll,
|
||||
1 + cursor - *scroll,
|
||||
1 + cpos,
|
||||
1 + cpos,
|
||||
"",
|
||||
input_shown - (cursor - *scroll),
|
||||
input_shown - (cursor - *scroll),
|
||||
input_shown_length - cpos,
|
||||
input_shown_length - cpos,
|
||||
""
|
||||
);
|
||||
}
|
||||
@ -163,8 +179,17 @@ static void MoveTextBoxCursor(const TouchBox* txtbox, const char* inputstr, cons
|
||||
const TouchBox* tb = TouchBoxGet(&id, x, y, txtbox, 0);
|
||||
if (id == KEY_TXTBOX) {
|
||||
u16 x_tb = x - tb->x;
|
||||
u16 cpos = (x_tb < (FONT_WIDTH_EXT/2)) ? 0 : (x_tb - (FONT_WIDTH_EXT/2)) / FONT_WIDTH_EXT;
|
||||
u32 cursor_next = *scroll + ((cpos <= input_shown) ? cpos : input_shown);
|
||||
|
||||
const u32 inputstr_size = strlen(inputstr);
|
||||
const u16 cpos_x = (x_tb < (FONT_WIDTH_EXT/2)) ? 0 : (x_tb - (FONT_WIDTH_EXT/2)) / FONT_WIDTH_EXT;
|
||||
u16 cpos_length = 0;
|
||||
u16 cpos_size = 0;
|
||||
while ((cpos_length < cpos_x && cpos_length < input_shown) || (*scroll + cpos_size < inputstr_size && (inputstr[*scroll + cpos_size] & 0xC0) == 0x80)) {
|
||||
if (*scroll + cpos_size >= inputstr_size || (inputstr[*scroll + cpos_size] & 0xC0) != 0x80) cpos_length++;
|
||||
cpos_size++;
|
||||
}
|
||||
|
||||
u32 cursor_next = *scroll + cpos_size;
|
||||
// move cursor to position pointed to
|
||||
if (*cursor != cursor_next) {
|
||||
if (cursor_next < max_size) *cursor = cursor_next;
|
||||
@ -173,10 +198,10 @@ static void MoveTextBoxCursor(const TouchBox* txtbox, const char* inputstr, cons
|
||||
}
|
||||
// move beyound visible field
|
||||
if (timer_msec(timer) >= scroll_cooldown) {
|
||||
if ((cpos == 0) && (*scroll > 0))
|
||||
(*scroll)--;
|
||||
else if ((cpos >= input_shown) && (*cursor < (max_size-1)))
|
||||
(*scroll)++;
|
||||
if ((cpos_length == 0) && (*scroll > 0))
|
||||
*scroll -= GetPrevCharSize(inputstr + *scroll);
|
||||
else if ((cpos_length >= input_shown) && (*cursor < (max_size-1)))
|
||||
*scroll += GetCharSize(inputstr + *scroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,16 +311,18 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) {
|
||||
break;
|
||||
} else if (key == KEY_BKSPC) {
|
||||
if (cursor) {
|
||||
int size = GetPrevCharSize(inputstr + cursor);
|
||||
if (cursor <= inputstr_size) {
|
||||
memmove(inputstr + cursor - 1, inputstr + cursor, inputstr_size - cursor + 1);
|
||||
inputstr_size--;
|
||||
memmove(inputstr + cursor - size, inputstr + cursor, inputstr_size - cursor + size);
|
||||
inputstr_size -= size;
|
||||
}
|
||||
cursor--;
|
||||
cursor -= size;
|
||||
}
|
||||
} else if (key == KEY_LEFT) {
|
||||
if (cursor) cursor--;
|
||||
if (cursor) cursor -= GetPrevCharSize(inputstr + cursor);
|
||||
} else if (key == KEY_RIGHT) {
|
||||
if (cursor < (max_size-1)) cursor++;
|
||||
int size = cursor > inputstr_size ? 1 : GetCharSize(inputstr + cursor);
|
||||
if (cursor + size < max_size) cursor += size;
|
||||
} else if (key == KEY_ALPHA) {
|
||||
swkbd = swkbd_alphabet;
|
||||
} else if (key == KEY_SPECIAL) {
|
||||
|
@ -476,6 +476,24 @@ u32 GetDrawStringHeight(const char* str) {
|
||||
return height;
|
||||
}
|
||||
|
||||
u32 GetCharSize(const char* str) {
|
||||
const char *start = str;
|
||||
do {
|
||||
str++;
|
||||
} while ((*str & 0xC0) == 0x80);
|
||||
|
||||
return str - start;
|
||||
}
|
||||
|
||||
u32 GetPrevCharSize(const char* str) {
|
||||
const char *start = str;
|
||||
do {
|
||||
str--;
|
||||
} while ((*str & 0xC0) == 0x80);
|
||||
|
||||
return start - str;
|
||||
}
|
||||
|
||||
u32 GetDrawStringWidth(const char* str) {
|
||||
u32 width = 0;
|
||||
char* old_lf = (char*) str;
|
||||
@ -994,7 +1012,7 @@ u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *f
|
||||
|
||||
bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alphabet, const char *format, va_list va) {
|
||||
const u32 alphabet_size = strnlen(alphabet, 256);
|
||||
const u32 input_shown = 22;
|
||||
const u32 input_shown_length = 22;
|
||||
const u32 fast_scroll = 4;
|
||||
const u64 aprv_delay = 128;
|
||||
|
||||
@ -1033,25 +1051,43 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha
|
||||
|
||||
while (true) {
|
||||
u32 inputstr_size = strnlen(inputstr, max_size - 1);
|
||||
if (cursor_s < scroll) scroll = cursor_s;
|
||||
else if (cursor_s - scroll >= input_shown) scroll = cursor_s - input_shown + 1;
|
||||
while (scroll && (inputstr_size - scroll < input_shown)) scroll--;
|
||||
DrawStringF(MAIN_SCREEN, x, y + str_height - 76, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c%-*.*s\n%-*.*s^%-*.*s",
|
||||
|
||||
if (cursor_s < scroll) {
|
||||
scroll = cursor_s;
|
||||
} else {
|
||||
int scroll_adjust = -input_shown_length;
|
||||
for (u32 i = scroll; i < cursor_s; i++) {
|
||||
if (i >= inputstr_size || (inputstr[i] & 0xC0) != 0x80) scroll_adjust++;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= scroll_adjust; i++)
|
||||
scroll += scroll >= inputstr_size ? 1 : GetCharSize(inputstr + scroll);
|
||||
}
|
||||
|
||||
u32 input_shown_size = 0;
|
||||
for (u32 i = 0; i < input_shown_length || (scroll + input_shown_size < inputstr_size && (inputstr[scroll + input_shown_size] & 0xC0) == 0x80); input_shown_size++) {
|
||||
if (scroll + input_shown_size >= inputstr_size || (inputstr[scroll + input_shown_size] & 0xC0) != 0x80) i++;
|
||||
}
|
||||
|
||||
u16 cpos = 0;
|
||||
for (u16 i = scroll; i < cursor_s; i++) {
|
||||
if (i >= inputstr_size || (inputstr[i] & 0xC0) != 0x80) cpos++;
|
||||
}
|
||||
|
||||
DrawStringF(MAIN_SCREEN, x, y + str_height - 76, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c\n%-*.*s^%-*.*s",
|
||||
(scroll) ? '<' : '|',
|
||||
(inputstr_size > input_shown) ? input_shown : inputstr_size,
|
||||
(inputstr_size > input_shown) ? input_shown : inputstr_size,
|
||||
inputstr + scroll,
|
||||
(inputstr_size - scroll > input_shown) ? '>' : '|',
|
||||
(inputstr_size > input_shown) ? 0 : input_shown - inputstr_size,
|
||||
(inputstr_size > input_shown) ? 0 : input_shown - inputstr_size,
|
||||
input_shown_size,
|
||||
input_shown_size,
|
||||
(scroll > inputstr_size) ? "" : inputstr + scroll,
|
||||
(inputstr_size - (s32) scroll > input_shown_size) ? '>' : '|',
|
||||
1 + cpos,
|
||||
1 + cpos,
|
||||
"",
|
||||
1 + cursor_s - scroll,
|
||||
1 + cursor_s - scroll,
|
||||
"",
|
||||
input_shown - (cursor_s - scroll),
|
||||
input_shown - (cursor_s - scroll),
|
||||
input_shown_length - cpos,
|
||||
input_shown_length - cpos,
|
||||
""
|
||||
);
|
||||
|
||||
if (cursor_a < 0) {
|
||||
for (cursor_a = alphabet_size - 1; (cursor_a > 0) && (alphabet[cursor_a] != inputstr[cursor_s]); cursor_a--);
|
||||
}
|
||||
@ -1091,11 +1127,26 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha
|
||||
}
|
||||
} else if (pad_state & BUTTON_X) {
|
||||
if (resize && (inputstr_size > resize)) {
|
||||
char* inputfrom = inputstr + cursor_s - (cursor_s % resize) + resize;
|
||||
char* inputto = inputstr + cursor_s - (cursor_s % resize);
|
||||
u32 char_index = 0;
|
||||
for(u32 i = 0; i < cursor_s; i++) {
|
||||
if (i >= inputstr_size || (inputstr[i] & 0xC0) != 0x80) char_index++;
|
||||
}
|
||||
|
||||
u32 to_index = char_index - (char_index % resize);
|
||||
u32 from_index = to_index + resize;
|
||||
|
||||
char* inputto = inputstr + cursor_s;
|
||||
for (u32 i = 0; i < char_index - to_index; i++) {
|
||||
inputto -= GetPrevCharSize(inputto);
|
||||
}
|
||||
char* inputfrom = inputto;
|
||||
for (u32 i = 0; i < from_index - to_index; i++) {
|
||||
inputfrom += GetCharSize(inputfrom);
|
||||
}
|
||||
|
||||
memmove(inputto, inputfrom, max_size - (inputfrom - inputstr));
|
||||
inputstr_size -= resize;
|
||||
while (cursor_s >= inputstr_size)
|
||||
inputstr_size -= inputfrom - inputto;
|
||||
while (cursor_s >= inputstr_size || (inputstr[cursor_s] & 0xC0) == 0x80)
|
||||
cursor_s--;
|
||||
cursor_a = -1;
|
||||
} else if (resize == 1) {
|
||||
@ -1112,18 +1163,29 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha
|
||||
cursor_a = 0;
|
||||
}
|
||||
} else if (pad_state & BUTTON_UP) {
|
||||
int size = GetCharSize(inputstr + cursor_s);
|
||||
if(size > 1) {
|
||||
memmove(inputstr + cursor_s, inputstr + cursor_s + size - 1, inputstr_size - cursor_s + size - 1);
|
||||
}
|
||||
|
||||
cursor_a += (pad_state & BUTTON_R1) ? fast_scroll : 1;
|
||||
cursor_a = cursor_a % alphabet_size;
|
||||
inputstr[cursor_s] = alphabet[cursor_a];
|
||||
} else if (pad_state & BUTTON_DOWN) {
|
||||
int size = GetCharSize(inputstr + cursor_s);
|
||||
if(size > 1) {
|
||||
memmove(inputstr + cursor_s, inputstr + cursor_s + size - 1, inputstr_size - cursor_s + size - 1);
|
||||
}
|
||||
|
||||
cursor_a -= (pad_state & BUTTON_R1) ? fast_scroll : 1;
|
||||
if (cursor_a < 0) cursor_a = alphabet_size + cursor_a;
|
||||
inputstr[cursor_s] = alphabet[cursor_a];
|
||||
} else if (pad_state & BUTTON_LEFT) {
|
||||
if (cursor_s > 0) cursor_s--;
|
||||
if (cursor_s > 0) cursor_s -= GetPrevCharSize(inputstr + cursor_s);
|
||||
cursor_a = -1;
|
||||
} else if (pad_state & BUTTON_RIGHT) {
|
||||
if (cursor_s < max_size - 2) cursor_s++;
|
||||
int size = cursor_s > inputstr_size ? 1 : GetCharSize(inputstr + cursor_s);
|
||||
if (cursor_s + size < max_size - 1) cursor_s += size;
|
||||
if (cursor_s >= inputstr_size) {
|
||||
memset(inputstr + cursor_s, alphabet[0], resize);
|
||||
inputstr[cursor_s + resize] = '\0';
|
||||
|
@ -66,6 +66,9 @@ void DrawString(u16 *screen, const char *str, int x, int y, u32 color, u32 bgcol
|
||||
void DrawStringF(u16 *screen, int x, int y, u32 color, u32 bgcolor, const char *format, ...);
|
||||
void DrawStringCenter(u16 *screen, u32 color, u32 bgcolor, const char *format, ...);
|
||||
|
||||
u32 GetCharSize(const char* str);
|
||||
u32 GetPrevCharSize(const char* str);
|
||||
|
||||
u32 GetDrawStringHeight(const char* str);
|
||||
u32 GetDrawStringWidth(const char* str);
|
||||
u32 GetFontWidth(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user