123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /*
- * ui_textosk.h
- * https://gitlab.com/bztsrc/smgui
- *
- * Copyright (C) 2024 bzt (bztsrc@gitlab), MIT license
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
- * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * @brief Text input with on screen keyboard for SMGUI
- */
- #ifndef UI_TEXTOSK_H
- #define UI_TEXTOSK_H 1
- #ifndef UI_H
- #include <ui.h>
- #undef UI_H
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define UI_FLAGS_NOOSK 256
- #define UI_TEXT UI_CUSTOM,.bbox=ui_textosk_bbox,.view=ui_textosk_view,.ctrl=ui_textosk_ctrl
- #define UI_SIZ _ui_textosk_popup[0].x
- #define UI_KBD _ui_textosk_popup[0].y
- #define UI_SCR _ui_textosk_popup[0].w
- #define UI_SEL _ui_textosk_popup[0].h
- #define UI_NUMKBD 13
- static ui_form_t _ui_textosk_popup[] = { { .type = UI_END } };
- typedef struct {
- char *id;
- int pair, num;
- const char **keys;
- } _ui_textosk_kbd_t;
- const char *_ui_textosk_numbers[] ={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "_", "-", "+", ".", "。", "$", "¢", "£", "¤",
- "¥", "§", "©", "®", "ª", "°", "¹", "²", "³", "½", "¼", "¾", "'", "/", NULL };
- const char *_ui_textosk_capital[] ={ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
- "U", "V", "W", "X", "Y", "Z", "ß", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ā", "Ă", "Ą", "Ç", "Ć", "Ĉ", "Ċ", "Č", "Ð", "Ď", "Đ",
- "È", "É", "Ê", "Ë", "Ē", "Ĕ", "Ė", "Ę", "Ě", "Ĝ", "Ğ", "Ġ", "Ģ", "Ĥ", "Ħ", "Ì", "Í", "Î", "Ï", "Ĩ", "Ī", "Ĭ", "Į", "İ", "Ĵ",
- "Ķ", "Ĺ", "Ļ", "Ľ", "Ŀ", "Ł", "Ñ", "Ń", "Ņ", "Ň", "Ŋ", "Ò", "Ó", "Ô", "Õ", "Ö", "Ø", "Ō", "Ŏ", "Ő", "Œ", "Ŕ", "Ŗ", "Ř", "Ś",
- "Ŝ", "Ş", "Š", "Ţ", "Ť", "Ŧ", "Ù", "Ú", "Û", "Ü", "Ũ", "Ū", "Ŭ", "Ů", "Ű", "Ų", "Ŵ", "Ý", "Ŷ", "Ÿ", "Þ", "Ź", "Ż", "Ž", NULL };
- const char *_ui_textosk_lower[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
- "u", "v", "w", "x", "y", "z", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ā", "ă", "ą", "ç", "ć", "ĉ", "ċ", "č", "ð", "ď", "đ",
- "è", "é", "ê", "ë", "ē", "ĕ", "ė", "ę", "ě", "ĝ", "ğ", "ġ", "ģ", "ĥ", "ħ", "ì", "í", "î", "ï", "ĩ", "ī", "ĭ", "į", "ı", "ĵ",
- "ķ", "ĺ", "ļ", "ľ", "ŀ", "ł", "ñ", "ń", "ņ", "ň", "ŋ", "ò", "ó", "ô", "õ", "ö", "ø", "ō", "ŏ", "ő", "œ", "ŕ", "ŗ", "ř", "ś",
- "ŝ", "ş", "š", "ţ", "ť", "ŧ", "ù", "ú", "û", "ü", "ũ", "ū", "ŭ", "ů", "ű", "ų", "ŵ", "ý", "ŷ", "ÿ", "þ", "ź", "ż", "ž", NULL };
- const char *_ui_textosk_greekc[] = { "Α", "Β", "Γ", "Δ", "Ε", "Ζ", "Η", "Θ", "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ", "Ο", "Π", "Ρ", "Σ", "Τ",
- "Υ", "Φ", "Χ", "Ψ", "Ω", "Ͱ", "Ͳ", "Ͷ", "Ϙ", "Ϛ", "Ϝ", "Ϟ", "Ϡ", "Ϣ", "Ϥ", "Ϧ", "Ϩ", "Ϫ", "Ϭ", "Ϯ", "Ϳ", "Ϻ", "Ͻ", "Ͼ", "Ͽ",
- "Ϸ", "Ά", "Έ", "Ή", "Ί", "Ϊ", "Ϋ", "Ό", "Ύ", "Ώ", "ϒ", "ϓ", "ϔ", NULL };
- const char *_ui_textosk_greekl[] = { "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "σ", "τ",
- "υ", "φ", "χ", "ψ", "ω", "ͱ", "ͳ", "ͷ", "ϙ", "ϛ", "ϝ", "ϟ", "ϡ", "ϣ", "ϥ", "ϧ", "ϩ", "ϫ", "ϭ", "ϯ", "ϳ", "ϻ", "ͻ", "ͼ", "ͽ",
- "ϸ", "ά", "έ", "ή", "ί", "ϊ", "ϋ", "ό", "ύ", "ώ", "ΐ", "ΰ", "ς", NULL };
- const char *_ui_textosk_cyrillc[] ={ "А", "Б", "В", "Г", "Д", "Е", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т",
- "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я", "Ѐ", "Ё", "Ђ", "Ѓ", "Є", "Ѕ", "І", "Ї", "Ј", "Љ", "Њ", "Ћ",
- "Ќ", "Ѝ", "Ў", "Џ", "Ѡ", "Ѣ", "Ѥ", "Ѧ", "Ѩ", "Ѫ", "Ѭ", "Ѯ", "Ѱ", "Ѳ", "Ѵ", "Ѷ", "Ѹ", "Ѻ", "Ѽ", "Ѿ", "Ҁ", NULL };
- const char *_ui_textosk_cyrilll[] ={ "а", "б", "в", "г", "д", "е", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т",
- "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я", "ѐ", "ё", "ђ", "ѓ", "є", "ѕ", "і", "ї", "ј", "љ", "њ", "ћ",
- "ќ", "ѝ", "ў", "џ", "ѡ", "ѣ", "ѥ", "ѧ", "ѩ", "ѫ", "ѭ", "ѯ", "ѱ", "ѳ", "ѵ", "ѷ", "ѹ", "ѻ", "ѽ", "ѿ", "ҁ", NULL };
- const char *_ui_textosk_hirac[] ={ "あ", "い", "う", "え", "お", "が", "ぎ", "ぐ", "げ", "ご", "ざ", "じ", "ず", "ぜ", "ぞ", "だ", "ぢ", "つ",
- "づ", "で", "ど", "に", "ね", "の", "ば", "ぱ", "び", "ぴ", "ぶ", "ぷ", "べ", "ぺ", "ぼ", "ぽ", "む", "も", "や", "ゆ", "よ", "り", "れ", "ろ",
- "わ", "ゑ", "ん", "ゕ", "ゖ", NULL };
- const char *_ui_textosk_hiral[] ={ "ぁ", "ぃ", "ぅ", "ぇ", "ぉ", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "っ",
- "づ", "て", "と", "な", "ぬ", "の", "は", "ぱ", "ひ", "ぴ", "ふ", "ぷ", "へ", "ぺ", "ほ", "ま", "み", "め", "ゃ", "ゅ", "ょ", "ら", "る", "ろ",
- "ゎ", "ゐ", "を", "ゔ", "ゖ", NULL };
- const char *_ui_textosk_katac[] ={ "ア", "イ", "ウ", "エ", "オ", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ツ",
- "ヅ", "デ", "ド", "ニ", "ネ", "ハ", "パ", "ビ", "ピ", "ブ", "プ", "ベ", "ペ", "ボ", "ポ", "マ", "ム", "モ", "ヤ", "ユ", "ヨ", "ラ", "ル", "ロ",
- "ワ", "ヴ", "ヸ", "ヹ", "ヺ", "ヵ", "ヶ", "・", NULL };
- const char *_ui_textosk_katal[] ={ "ァ", "ィ", "ゥ", "ェ", "ォ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ッ",
- "ヅ", "テ", "ト", "ナ", "ヌ", "ノ", "バ", "ヒ", "ピ", "フ", "プ", "ヘ", "ペ", "ホ", "ポ", "マ", "ミ", "メ", "ャ", "ュ", "ョ", "ラ", "リ", "レ",
- "ヮ", "ヷ", "ヰ", "ヱ", "ヲ", "ン", "ヶ", "・", NULL };
- const char *_ui_textosk_hebrew[] = { "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י", "ך", "כ", "ל", "ם", "מ", "ן", "נ", "ס", "ע", "ף",
- "פ", "ץ", "צ", "ק", "ר", "ש", "ת", NULL };
- const char *_ui_textosk_devana[] = { "ऄ", "अ", "आ", "इ", "ई", "उ", "ऊ", "ऋ", "ऌ", "ऍ", "ऎ", "ए", "ऐ", "ऑ", "ऒ", "ओ",
- "औ", "क", "ख", "ग", "घ", "ङ", "च", "छ", "ज", "झ", "ञ", "ट", "ठ", "ड", "ढ", "ण", "त", "थ", "द", "ध", "न",
- "ऩ", "प", "फ", "ब", "भ", "म", "य", "र", "ऱ", "ल", "ळ", "ऴ", "व", "श", "ष", "स", "ह", "ॐ", "क़", "ख़", "ग़",
- "ज़", "ड़", "ढ़", "फ़", "य़", "ॠ", "ॡ", "ॲ", "ॳ", "ॴ", "ॵ", "ॶ", "ॷ", "ॸ", "ॹ", "ॺ", "ॻ", "ॼ", "ॽ", "ॾ", "ॿ", NULL };
- _ui_textosk_kbd_t _ui_textosk_keyboards[UI_NUMKBD] = {
- { "0", 0, 0, _ui_textosk_numbers },
- { "A", 2, 0, _ui_textosk_capital },
- { "a", 1, 0, _ui_textosk_lower },
- { "Γ", 4, 0, _ui_textosk_greekc },
- { "γ", 3, 0, _ui_textosk_greekl },
- { "Б", 6, 0, _ui_textosk_cyrillc },
- { "б", 5, 0, _ui_textosk_cyrilll },
- { "あ", 8, 0, _ui_textosk_hirac },
- { "ぁ", 7, 0, _ui_textosk_hiral },
- { "ア", 10, 0, _ui_textosk_katac },
- { "ァ", 9, 0, _ui_textosk_katal },
- { "א", 0, 0, _ui_textosk_hebrew },
- { "ऄ", 0, 0, _ui_textosk_devana }
- };
- /* we must not rely on all fonts always have these glyphs */
- uint16_t _ui_textosk_glyphs[6*16] = {
- 0,0,0,1024,1536,1792,1920,1984,2016,1984,1920,1792,1536,1024,0,0,0,0,0,32,96,224,480,992,2016,992,480,224,96,32,0,0,0,0,65504,
- 32784,32776,34948,34050,33281,34050,34948,32776,32784,65504,0,0,0,0,0,0,0,0,32,48,8184,8184,48,32,0,0,0,0,0,0,0,0,0,0,1024,3072,
- 8184,8184,3072,1024,0,0,0,0,0,0,0,0,12288,12288,12320,12336,12344,16380,16380,56,48,32,0,0,0
- };
- /**
- * Display an osk key
- */
- void _ui_textosk_key(ui_t *ctx, int x, int y, int w, int h, int pressed, char *str)
- {
- uint32_t fg = 0xff7f7f7f, bg = 0xff020202;
- int dw = 0, dh = 0, l = 0, t = 0;
- if(pressed == 2) { fg = 0xffffffff; bg = 0xff003f00; }
- if(pressed == 1) { fg = 0xffffffff; bg = 0xff3f0000; }
- if(pressed == -1) { fg = 0xff020202; bg = 0xff080808; }
- _ui_rect(ctx, x, y, w, h, bg, 0, bg);
- _ui_frect(ctx, x + 1, y + 1, w - 2, h - 2, bg);
- if(str) {
- if(str[0] > 0 && str[0] < 7) {
- _ui_bmp16(ctx, x + (w - 16)/2, y + (h - 16)/2, &_ui_textosk_glyphs[((int)str[0] - 1) << 4], fg);
- } else
- if(ctx->fnt && ctx->bbox && ctx->draw) {
- (*ctx->bbox)(ctx->fnt, str, NULL, &dw, &dh, &l, &t);
- (*ctx->draw)(ctx->fnt, str, NULL, ctx->screen.buf, fg, x - l + (w - dw)/2, y + (h - dh)/2, l, t, ctx->screen.p,
- ctx->cx0 + 1, ctx->cy0 + 1, ctx->cx1 - 1, ctx->cy1 - 1);
- }
- }
- }
- /**
- * Recalculate form element bounding box
- */
- int ui_textosk_bbox(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form, int *dw, int *dh)
- {
- if(!ctx || !form || !dw || !dh) return UI_ERR_BADINP;
- (void)x; (void)y; (void)w; (void)h;
- if(ctx->fnt && ctx->bbox && form->ptr) {
- /* if string is empty, use a default one to get height and baseline correctly */
- (*ctx->bbox)(ctx->fnt, form->ptr, NULL, dw, dh, &form->l, &form->t);
- if(!form->ptr || !*((char*)form->ptr)) { *dw = 0; *dh = ctx->ds; form->t = ctx->dt; }
- (*dh) += 4;
- }
- if(form->ew > 0) *dw = form->ew;
- return UI_OK;
- }
- /**
- * Display a text input field and an OSK
- */
- int ui_textosk_view(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form)
- {
- int i, j, c;
- if(!ctx || !form) return UI_ERR_BADINP;
- if(form == _ui_textosk_popup) {
- /* draw the osk */
- _ui_frect(ctx, ctx->px, ctx->py, ctx->pw, ctx->ph, 0xcf000000);
- y = ctx->py + 8; w = ctx->pw / 12; h = (ctx->ph - 24) / 5; c = (w < h ? w : h) - 4;
- j = (ctx->pw - w) / UI_NUMKBD;
- for(i = 0, x = w / 2; i < UI_NUMKBD; i++, x += j)
- _ui_textosk_key(ctx, x + (j - c) / 2, y + (h - c) / 2, c, c,
- UI_SEL == i ? 1 : (UI_KBD == i ? 2 : 0), (char*)_ui_textosk_keyboards[i].id);
- y += h + 8;
- for(i = j = 0; j < 3; j++, y += h)
- for(x = 0; x < 12 && i + UI_SCR < _ui_textosk_keyboards[UI_KBD].num; x++, i++)
- _ui_textosk_key(ctx, x * w + (w - c) / 2, y + (h - c) / 2, c, c,
- UI_SEL == UI_NUMKBD + i, (char*)_ui_textosk_keyboards[UI_KBD].keys[i + UI_SCR]);
- _ui_textosk_key(ctx, (w - c) / 2, y + (h - c) / 2, c, c, UI_SCR ? UI_SEL == UI_NUMKBD + 36 : -1, "\x1");
- _ui_textosk_key(ctx, w + (w - c) / 2, y + (h - c) / 2, c, c, UI_SCR + 36 < _ui_textosk_keyboards[UI_KBD].num ?
- UI_SEL == UI_NUMKBD + 37 : -1, "\x2");
- _ui_textosk_key(ctx, 2 * w + (w - c) / 2, y + (h - c) / 2, c, c, UI_SEL == UI_NUMKBD + 38, "\x3");
- _ui_textosk_key(ctx, 3 * w + (w - c) / 2, y + (h - c) / 2, c + 4 * w, c, UI_SEL == UI_NUMKBD + 39, " ");
- _ui_textosk_key(ctx, 8 * w + (w - c) / 2, y + (h - c) / 2, c, c, UI_SEL == UI_NUMKBD + 40, "\x4");
- _ui_textosk_key(ctx, 9 * w + (w - c) / 2, y + (h - c) / 2, c, c, UI_SEL == UI_NUMKBD + 41, "\x5");
- _ui_textosk_key(ctx, 10 * w + (w - c) / 2, y + (h - c) / 2, c + w, c, UI_SEL == UI_NUMKBD + 42, "\x6");
- } else
- /* draw the input field */
- _ui_text(ctx, x, y, w, h, form->l, form->t, form->flags, (ctx->text == form) | (form->inc == UI_FILTER_PASS ? 2 : 0),
- form->ptr, NULL);
- return UI_OK;
- }
- /**
- * Process events
- */
- int ui_textosk_ctrl(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form, ui_event_t *evt)
- {
- static int joydir = 0;
- int i, j, dw, dh;
- char keystr[8] = { 0 };
- if(!ctx || !form || !evt) return UI_ERR_BADINP;
- if(!ctx->popup && evt->type == UI_EVT_MOUSE && (evt->btn & UI_BTN_L)) {
- /* user clicked on the text input field */
- if(form->ptr && form->max > 0) {
- evt->type = UI_EVT_NONE;
- ((char*)form->ptr)[form->max - 1] = 0;
- _ui_text_start(ctx, x, y, w, h, form, form->ptr, form->max);
- if(!(ctx->flags & UI_FLAGS_NOOSK)) {
- ctx->popup = _ui_textosk_popup;
- ctx->dr = ui_textosk_view;
- ctx->pe = ui_textosk_ctrl;
- ctx->px = 0;
- ctx->pw = ctx->screen.w;
- for(j = 0; j < UI_NUMKBD; j++) {
- if(!_ui_textosk_keyboards[j].num) {
- for(i = 0; _ui_textosk_keyboards[j].keys[i]; i++)
- if(ctx->fnt && ctx->bbox) {
- (*ctx->bbox)(ctx->fnt, (char*)_ui_textosk_keyboards[j].keys[i], NULL, &dw, &dh, NULL, NULL);
- if(UI_SIZ < dw) UI_SIZ = dw;
- if(UI_SIZ < dh) UI_SIZ = dh;
- }
- _ui_textosk_keyboards[j].num = i;
- }
- }
- ctx->ph = (UI_SIZ + 16) * 5 + 24;
- ctx->py = ctx->screen.h - ctx->ph;
- UI_SEL = -1;
- }
- }
- } else
- if(ctx->popup) {
- /* popup event handler */
- if(evt->type == UI_EVT_MOUSE) {
- /* touchpad */
- if(!(evt->btn & UI_BTN_RELEASE)) {
- UI_SEL = -1;
- y = ctx->py + 8; w = ctx->pw / 12; h = (ctx->ph - 24) / 5;
- if(ctx->mousey < ctx->py + 8 + h && ctx->mousex >= w / 2) {
- j = (ctx->pw - w) / UI_NUMKBD;
- i = (ctx->mousex - w / 2) / j;
- if(i < UI_NUMKBD) UI_SEL = i;
- } else
- if(ctx->mousey >= ctx->py + 16 + h && ctx->mousey < ctx->py + 16 + 4 * h) {
- i = (ctx->mousey - ctx->py - 16 - h) / h * 12 + ctx->mousex / w;
- if(i + UI_SCR < _ui_textosk_keyboards[UI_KBD].num) {
- UI_SEL = UI_NUMKBD + i;
- }
- } else
- if(ctx->mousey >= ctx->py + 16 + 4 * h) {
- if(ctx->mousex < w) UI_SEL = UI_NUMKBD + 36; else
- if(ctx->mousex < 2 * w) UI_SEL = UI_NUMKBD + 37; else
- if(ctx->mousex < 3 * w) UI_SEL = UI_NUMKBD + 38; else
- if(ctx->mousex < 8 * w) UI_SEL = UI_NUMKBD + 39; else
- if(ctx->mousex < 9 * w) UI_SEL = UI_NUMKBD + 40; else
- if(ctx->mousex < 10 * w) UI_SEL = UI_NUMKBD + 41; else UI_SEL = UI_NUMKBD + 42;
- }
- setsel: memset(keystr, 0, sizeof(keystr));
- if(UI_SEL >= 0 && UI_SEL < UI_NUMKBD) {
- if(_ui_textosk_keyboards[UI_SEL].pair != UI_KBD) UI_SCR = 0;
- UI_KBD = UI_SEL;
- } else
- if(UI_SEL >= UI_NUMKBD && UI_SEL < UI_NUMKBD + 36) {
- if(UI_SEL - UI_NUMKBD + UI_SCR < _ui_textosk_keyboards[UI_KBD].num)
- memcpy(keystr, _ui_textosk_keyboards[UI_KBD].keys[UI_SEL - UI_NUMKBD + UI_SCR], 4);
- } else
- if(UI_SEL == UI_NUMKBD + 36) { if(UI_SCR >= 36) UI_SCR -= 36; else UI_SCR = 0; } else
- if(UI_SEL == UI_NUMKBD + 37) { if(UI_SCR + 36 < _ui_textosk_keyboards[UI_KBD].num) UI_SCR += 36; } else
- if(UI_SEL == UI_NUMKBD + 38) keystr[0] = '\b'; else
- if(UI_SEL == UI_NUMKBD + 39) keystr[0] = ' '; else
- if(UI_SEL == UI_NUMKBD + 40) memcpy(keystr, "Left", 5); else
- if(UI_SEL == UI_NUMKBD + 41) memcpy(keystr, "Right", 6); else
- if(UI_SEL == UI_NUMKBD + 42) keystr[0] = '\n';
- if(UI_SEL == UI_NUMKBD + 36 && !UI_SCR) UI_SEL++;
- if(UI_SEL == UI_NUMKBD + 37 && UI_SCR + 36 >= _ui_textosk_keyboards[UI_KBD].num) { if(UI_SCR) UI_SEL--; else UI_SEL++; }
- } else UI_SEL = -1;
- if(keystr[0]) {
- memset(evt, 0, sizeof(ui_event_t));
- memcpy(evt->key, keystr, 8);
- evt->type = UI_EVT_KEY;
- _ui_text_ctrl(ctx, evt);
- memset(evt, 0, sizeof(ui_event_t));
- }
- } else
- if(evt->type == UI_EVT_KEY && (evt->btn & UI_BTN_GUI)) {
- /* fake "gamepad" */
- if(UI_SEL < 0) UI_SEL = 0;
- if(!memcmp(evt->key, "Up", 3)) goto up;
- if(!memcmp(evt->key, "Down", 5)) goto down;
- if(!memcmp(evt->key, "Left", 5)) goto left;
- if(!memcmp(evt->key, "Right", 6)) goto right;
- if(evt->key[0] == '\n' || evt->key[0] == ' ') goto setsel;
- } else
- if(evt->type == UI_EVT_GAMEPAD) {
- /* gamepad */
- if(UI_SEL < 0) UI_SEL = 0;
- if(evt->x < -8000 || evt->rx < -8000) joydir = UI_BTN_L;
- if(evt->x > 8000 || evt->rx > 8000) joydir = UI_BTN_R;
- if(evt->y < -8000 || evt->ry < -8000) joydir = UI_BTN_U;
- if(evt->y > 8000 || evt->ry > 8000) joydir = UI_BTN_D;
- if(evt->x > -8000 && evt->x < 8000 && evt->y > -8000 && evt->y < 8000 &&
- evt->rx > -8000 && evt->rx < 8000 && evt->ry > -8000 && evt->ry < 8000 && joydir) {
- evt->btn |= joydir; joydir = 0;
- }
- if(evt->btn & UI_BTN_U) {
- up: if(UI_SEL - 12 < UI_NUMKBD) {
- w = ctx->pw / 12; j = (ctx->pw - w) / UI_NUMKBD;
- UI_SEL = (UI_SEL - UI_NUMKBD) * w / j;
- } else
- if(UI_SEL >= UI_NUMKBD + 36) {
- i = UI_SEL - UI_NUMKBD - 36; if(i > 3) i += 4;
- i += UI_SCR + 36 < _ui_textosk_keyboards[UI_KBD].num ? 24 : ((_ui_textosk_keyboards[UI_KBD].num % 36) / 12) * 12;
- if(i + UI_SCR >= _ui_textosk_keyboards[UI_KBD].num) i -= 12;
- UI_SEL = UI_NUMKBD + i;
- } else UI_SEL -= 12;
- if(UI_SEL < 0 || UI_SEL > UI_NUMKBD + 42) UI_SEL = UI_NUMKBD + 42;
- } else
- if(evt->btn & UI_BTN_L) {
- left: if(UI_SEL > 0) UI_SEL--; else UI_SEL = UI_NUMKBD + 42;
- if(UI_SEL == UI_NUMKBD + 37 && UI_SCR + 36 >= _ui_textosk_keyboards[UI_KBD].num) UI_SEL--;
- if(UI_SEL == UI_NUMKBD + 36 && !UI_SCR) UI_SEL--;
- if(UI_SEL > UI_NUMKBD && UI_SEL < UI_NUMKBD + 36 && UI_SEL - UI_NUMKBD + UI_SCR >= _ui_textosk_keyboards[UI_KBD].num)
- UI_SEL = UI_NUMKBD + (_ui_textosk_keyboards[UI_KBD].num % 36) - 1;
- } else
- if(evt->btn & UI_BTN_R) {
- right: UI_SEL++;
- if(UI_SEL > UI_NUMKBD + 42) UI_SEL = 0;
- if(UI_SEL - UI_NUMKBD + UI_SCR >= _ui_textosk_keyboards[UI_KBD].num) UI_SEL = UI_NUMKBD + 36;
- if(UI_SEL == UI_NUMKBD + 36 && !UI_SCR) UI_SEL++;
- if(UI_SEL == UI_NUMKBD + 37 && UI_SCR + 36 >= _ui_textosk_keyboards[UI_KBD].num) UI_SEL++;
- } else
- if(evt->btn & UI_BTN_D) {
- down: if(UI_SEL < UI_NUMKBD) {
- w = ctx->pw / 12; j = (ctx->pw - w) / UI_NUMKBD;
- UI_SEL = UI_NUMKBD + ((w + UI_SEL * j) / w);
- } else {
- UI_SEL += 12;
- i = UI_SEL - UI_NUMKBD + UI_SCR;
- if(i >= _ui_textosk_keyboards[UI_KBD].num || i - UI_SCR >= 36) {
- i = (UI_SEL - UI_NUMKBD) % 12;
- UI_SEL = UI_NUMKBD + 36 + (i < 4 ? i : (i < 8 ? 3 : i - 4));
- }
- if(UI_SEL == UI_NUMKBD + 36 && !UI_SCR) UI_SEL++;
- if(UI_SEL == UI_NUMKBD + 37 && UI_SCR + 36 >= _ui_textosk_keyboards[UI_KBD].num) UI_SEL++;
- }
- if(UI_SEL < 0 || UI_SEL > UI_NUMKBD + 42) UI_SEL = UI_NUMKBD + 42;
- } else
- if(evt->btn & UI_BTN_BA) {
- ctx->flags |= UI_CLOSE;
- _ui_text_ctrl(ctx, evt);
- } else
- if(evt->btn & (UI_BTN_A | UI_BTN_B | UI_BTN_X | UI_BTN_Y)) goto setsel;
- }
- }
- return UI_OK;
- }
- #undef UI_SIZ
- #undef UI_KBD
- #undef UI_SCR
- #undef UI_SEL
- #undef UI_NUMKBD
- #ifdef __cplusplus
- }
- #endif
- #endif /* UI_TEXTOSK_H */
|