From: teru Date: Sun, 27 Jun 2010 14:03:59 +0000 (+0000) Subject: FS#10925 by myself: add touchscreen support for virtual keyboard. X-Git-Url: https://repo.or.cz/w/kugel-rb.git/commitdiff_plain/aeeab30b0ead67110e17d01ed241fea2edf05d2e FS#10925 by myself: add touchscreen support for virtual keyboard. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27156 a1c6a512-1295-4272-9138-f99709370657 --- diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 49ce9b25a..2c09b594b 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -12554,3 +12554,54 @@ *: "open picture flow" + + id: LANG_KBD_OK + desc: in keyboad + user: core + + *: none + touchscreen: "OK" + + + *: none + touchscreen: "OK" + + + *: none + touchscreen: "OK" + + + + id: LANG_KBD_DELETE + desc: in keyboad + user: core + + *: none + touchscreen: "Del" + + + *: none + touchscreen: "Del" + + + *: none + touchscreen: "Del" + + + + id: LANG_KBD_CANCEL + desc: in keyboad + user: core + + *: none + touchscreen: "Cancel" + + + *: none + touchscreen: "Cancel" + + + *: none + touchscreen: "Cancel" + + diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c index e8894d179..2ec14a8d0 100644 --- a/apps/recorder/keyboard.c +++ b/apps/recorder/keyboard.c @@ -47,6 +47,12 @@ #define DEFAULT_MARGIN 6 #define KBD_BUF_SIZE 500 +#ifdef HAVE_TOUCHSCREEN +#define MIN_GRID_SIZE 16 +#define GRID_SIZE(s, x) \ + ((s) == SCREEN_MAIN && MIN_GRID_SIZE > (x) ? MIN_GRID_SIZE: (x)) +#endif + #if (CONFIG_KEYPAD == IRIVER_H100_PAD) \ || (CONFIG_KEYPAD == IRIVER_H300_PAD) \ || (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ @@ -93,6 +99,9 @@ struct keyboard_parameters int x; int y; bool line_edit; +#ifdef HAVE_TOUCHSCREEN + bool show_buttons; +#endif }; struct edit_state @@ -272,6 +281,11 @@ static void kbd_draw_picker(struct keyboard_parameters *pm, struct screen *sc, struct edit_state *state); static void kbd_draw_edit_line(struct keyboard_parameters *pm, struct screen *sc, struct edit_state *state); +#ifdef HAVE_TOUCHSCREEN +static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc); +static int keyboard_touchscreen(struct keyboard_parameters *pm, + struct screen *sc, struct edit_state *state); +#endif static void kbd_insert_selected(struct keyboard_parameters *pm, struct edit_state *state); static void kbd_backspace(struct edit_state *state); @@ -414,6 +428,10 @@ int kbd_input(char* text, int buflen) sc->clear_display(); kbd_draw_picker(pm, sc, &state); kbd_draw_edit_line(pm, sc, &state); +#ifdef HAVE_TOUCHSCREEN + if (pm->show_buttons) + kbd_draw_buttons(pm, sc); +#endif } #ifdef HAVE_BUTTONBAR @@ -437,6 +455,10 @@ int kbd_input(char* text, int buflen) #endif pm = ¶m[button_screen]; sc = &screens[button_screen]; +#ifdef HAVE_TOUCHSCREEN + if (button == ACTION_TOUCHSCREEN) + button = keyboard_touchscreen(pm, sc, &state); +#endif /* Remap some buttons to allow to move * cursor in line edit mode and morse mode. */ @@ -652,6 +674,12 @@ static void kbd_calc_params(struct keyboard_parameters *pm, unsigned short ch; int icon_w, sc_w, sc_h, w; int i, total_lines; +#ifdef HAVE_TOUCHSCREEN + int button_h = 0; + bool flippage_button = false; + pm->show_buttons = (sc->screen_type == SCREEN_MAIN && + (touchscreen_get_mode() == TOUCHSCREEN_POINT)); +#endif pm->curfont = pm->default_lines ? FONT_SYSFIXED : FONT_UI; font = font_get(pm->curfont); @@ -664,6 +692,9 @@ static void kbd_calc_params(struct keyboard_parameters *pm, font = font_get(FONT_SYSFIXED); pm->font_h = font->height; } +#ifdef HAVE_TOUCHSCREEN + pm->font_h = GRID_SIZE(sc->screen_type, pm->font_h); +#endif /* find max width of keyboard glyphs. * since we're going to be adding spaces, @@ -690,6 +721,9 @@ static void kbd_calc_params(struct keyboard_parameters *pm, pm->text_w = w; } +#ifdef HAVE_TOUCHSCREEN + pm->font_w = GRID_SIZE(sc->screen_type, pm->font_w); +#endif /* calculate how many characters to put in a row. */ icon_w = get_icon_width(sc->screen_type); sc_w = sc->getwidth(); @@ -750,6 +784,16 @@ static void kbd_calc_params(struct keyboard_parameters *pm, /* calculate pm->pages and pm->lines */ sc_h = sc->getheight(); +#ifdef HAVE_TOUCHSCREEN + /* add space for buttons */ + if (pm->show_buttons) + { + /* reserve place for OK/Del/Cancel buttons, use ui font for them */ + button_h = GRID_SIZE(sc->screen_type, sc->getcharheight()); + sc_h -= MAX(MIN_GRID_SIZE*2, button_h); + } +recalc_param: +#endif pm->lines = (sc_h - BUTTONBAR_HEIGHT) / pm->font_h - 1; if (pm->default_lines && pm->lines > pm->default_lines) @@ -770,9 +814,23 @@ static void kbd_calc_params(struct keyboard_parameters *pm, total_lines = (pm->nchars + pm->max_chars - 1) / pm->max_chars; pm->pages = (total_lines + pm->lines - 1) / pm->lines; pm->lines = (total_lines + pm->pages - 1) / pm->pages; +#ifdef HAVE_TOUCHSCREEN + if (pm->pages > 1 && pm->show_buttons && !flippage_button) + { + /* add space for flip page button */ + sc_h -= button_h; + flippage_button = true; + goto recalc_param; + } +#endif pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin; pm->keyboard_margin -= pm->keyboard_margin/2; +#ifdef HAVE_TOUCHSCREEN + /* flip page button is put between piker and edit line */ + if (flippage_button) + pm->main_y += button_h; +#endif #ifdef HAVE_MORSE_INPUT pm->old_main_y = sc_h - pm->font_h - BUTTONBAR_HEIGHT; @@ -849,14 +907,14 @@ static void kbd_draw_picker(struct keyboard_parameters *pm, for (i = j = 0; k < pm->nchars; k++) { - int w; + int w, h; unsigned char *utf8; utf8 = utf8encode(pm->kbd_buf[k], outline); *utf8 = 0; - sc->getstringsize(outline, &w, NULL); + sc->getstringsize(outline, &w, &h); sc->putsxy(i*pm->font_w + (pm->font_w-w) / 2, - j*pm->font_h, outline); + j*pm->font_h + (pm->font_h-h) / 2, outline); if (++i >= pm->max_chars) { @@ -961,6 +1019,113 @@ static void kbd_draw_edit_line(struct keyboard_parameters *pm, } } +#ifdef HAVE_TOUCHSCREEN +static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc) +{ + struct viewport vp; + int button_h, text_h, text_y; + int sc_w = sc->getwidth(), sc_h = sc->getheight(); + viewport_set_defaults(&vp, sc->screen_type); + vp.flags |= VP_FLAG_ALIGN_CENTER; + sc->set_viewport(&vp); + text_h = sc->getcharheight(); + button_h = GRID_SIZE(sc->screen_type, text_h); + text_y = (button_h - text_h) / 2 + 1; + vp.x = 0; + vp.y = 0; + vp.width = sc_w; + vp.height = button_h; + /* draw buttons */ + if (pm->pages > 1) + { + /* button to flip page. */ + vp.y = pm->lines*pm->font_h; + sc->hline(0, sc_w - 1, 0); + sc->putsxy(0, text_y, ">"); + } + /* OK/Del/Cancel buttons */ + button_h = MAX(MIN_GRID_SIZE*2, button_h); + text_y = (button_h - text_h) / 2 + 1; + vp.y = sc_h - button_h - 1; + vp.height = button_h; + sc->hline(0, sc_w - 1, 0); + vp.width = sc_w/3; + sc->putsxy(0, text_y, str(LANG_KBD_OK)); + vp.x += vp.width; + sc->vline(0, 0, button_h); + sc->putsxy(0, text_y, str(LANG_KBD_DELETE)); + vp.x += vp.width; + sc->vline(0, 0, button_h); + sc->putsxy(0, text_y, str(LANG_KBD_CANCEL)); + sc->set_viewport(NULL); +} + +static int keyboard_touchscreen(struct keyboard_parameters *pm, + struct screen *sc, struct edit_state *state) +{ + short x, y; + const int button = action_get_touchscreen_press(&x, &y); + const int sc_w = sc->getwidth(), sc_h = sc->getheight(); + int button_h = MAX(MIN_GRID_SIZE*2, sc->getcharheight()); +#ifdef HAVE_MORSE_INPUT + if (state->morse_mode && y < pm->main_y - pm->keyboard_margin) + { + /* don't return ACTION_NONE since it has effect in morse mode. */ + return button == BUTTON_TOUCHSCREEN? ACTION_KBD_SELECT: + button & BUTTON_REL? ACTION_KBD_MORSE_SELECT: ACTION_STD_OK; + } +#else + (void) state; +#endif + if (x < 0 || y < 0) + return ACTION_NONE; + if (y < pm->lines*pm->font_h) + { + if (x/pm->font_w < pm->max_chars) + { + /* picker area */ + state->changed = CHANGED_PICKER; + pm->x = x/pm->font_w; + pm->y = y/pm->font_h; + pm->line_edit = false; + if (button == BUTTON_REL) + return ACTION_KBD_SELECT; + } + } + else if (y < pm->main_y - pm->keyboard_margin) + { + /* button to flip page */ + if (button == BUTTON_REL) + return ACTION_KBD_PAGE_FLIP; + } + else if (y < sc_h - button_h) + { + /* edit line */ + if (button & (BUTTON_REPEAT|BUTTON_REL)) + { + if (x < sc_w/2) + return ACTION_KBD_CURSOR_LEFT; + else + return ACTION_KBD_CURSOR_RIGHT; + } + } + else + { + /* OK/Del/Cancel button */ + if (button == BUTTON_REL) + { + if (x < sc_w/3) + return ACTION_KBD_DONE; + else if (x < (sc_w/3) * 2) + return ACTION_KBD_BACKSPACE; + else + return ACTION_KBD_ABORT; + } + } + return ACTION_NONE; +} +#endif + /* inserts the selected char */ static void kbd_insert_selected(struct keyboard_parameters *pm, struct edit_state *state)