From 5c55e7f8ad442b1f9c4617bff6a4fff2ee25fdf1 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sun, 6 Feb 2005 23:23:49 +0000 Subject: New virtual keyboard for player: (1) Much more user friendly (button directions, no submenu). (2) Now voiced like the recorder keypad. (3) More compact and straightforward code. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5819 a1c6a512-1295-4272-9138-f99709370657 --- apps/player/keyboard.c | 422 ++++++++++++++++++++++--------------------------- 1 file changed, 188 insertions(+), 234 deletions(-) (limited to 'apps') diff --git a/apps/player/keyboard.c b/apps/player/keyboard.c index 7752ce3ff7..76f64fbc88 100644 --- a/apps/player/keyboard.c +++ b/apps/player/keyboard.c @@ -19,13 +19,16 @@ #include "lcd.h" #include "button.h" #include "kernel.h" +#include "system.h" #include "version.h" #include "debug_menu.h" #include "sprintf.h" #include #include "lcd-player-charset.h" -#include "lang.h" -#include "debug.h" +#include "settings.h" +#include "status.h" +#include "talk.h" +#include "misc.h" #define KEYBOARD_PAGES 3 @@ -38,27 +41,28 @@ static unsigned short* kbd_setupkeys(int page, int* len) unsigned short ch; int i = 0; - switch (page) { - case 0: /* Capitals */ - for (ch = 'A'; ch <= 'Z'; ch++) - lines[i++] = ch; - for (ch = 0xc0; ch <= 0xdd; ch++) - if (lcd_ascii[ch] != NOCHAR_NEW && lcd_ascii[ch] != NOCHAR_OLD) + switch (page) + { + case 0: /* Capitals */ + for (ch = 'A'; ch <= 'Z'; ch++) lines[i++] = ch; - break; + for (ch = 0xc0; ch <= 0xdd; ch++) + if (lcd_ascii[ch] != NOCHAR_NEW && lcd_ascii[ch] != NOCHAR_OLD) + lines[i++] = ch; + break; - case 1: /* Small */ - for (ch = 'a'; ch <= 'z'; ch++) - lines[i++] = ch; - for (ch = 0xdf; ch <= 0xff; ch++) - if (lcd_ascii[ch] != NOCHAR_NEW && lcd_ascii[ch] != NOCHAR_OLD) + case 1: /* Small */ + for (ch = 'a'; ch <= 'z'; ch++) lines[i++] = ch; - break; + for (ch = 0xdf; ch <= 0xff; ch++) + if (lcd_ascii[ch] != NOCHAR_NEW && lcd_ascii[ch] != NOCHAR_OLD) + lines[i++] = ch; + break; - case 2: /* Others */ - for (ch = ' '; ch <= '@'; ch++) - lines[i++] = ch; - break; + case 2: /* Others */ + for (ch = ' '; ch <= '@'; ch++) + lines[i++] = ch; + break; } lines[i] = 0; @@ -74,254 +78,204 @@ static unsigned short* kbd_setupkeys(int page, int* len) #define KEYBOARD_CURSOR 0x7f #define KEYBOARD_ARROW 0x92 -#define MENU_LINE_INPUT 0 -#define MENU_LINE_NEWCHARS 1 -#define MENU_LINE_BACKSPACE 2 -#define MENU_LINE_DELETE 3 -#define MENU_LINE_ACCEPT 4 -#define MENU_LINE_QUIT 5 -#define MENU_LINE_LAST 5 +/* helper function to spell a char if voice UI is enabled */ +static void kbd_spellchar(char c) +{ + static char spell_char[2] = "\0\0"; /* store char to pass to talk_spell */ + + if (global_settings.talk_menu) /* voice UI? */ + { + spell_char[0] = c; + talk_spell(spell_char, false); + } +} int kbd_input(char* text, int buflen) { bool done = false; - int page=0, x=0; + bool redraw = true; + bool line_edit = false; + int page = 0, x = 0; int linelen; + + int len, i; + int editpos, curpos, leftpos; unsigned short* line = kbd_setupkeys(page, &linelen); - int menu_line=0; - int cursor_pos=0; - int button_pressed; unsigned char temptext[12]; - int old_cursor_pos=0; /* Windowed cursor movement */ - int left_pos=0; - - lcd_clear_display(); - - old_cursor_pos=cursor_pos=strlen(text); - if (9 0) { - if(scrpos > 7) { - left_pos = cursor_pos - 9; - if(left_pos < 0) - left_pos = 0; - if(left_pos > len - 9) - left_pos = len - 9; - } - } + char c; - p=0; - i = left_pos; - while (p<10 && text[i]) { - temptext[p++]=text[i++]; + int button, lastbutton = 0; + + editpos = strlen(text); + + if (global_settings.talk_menu) /* voice UI? */ + talk_spell(text, true); /* spell initial text */ + + while (!done) + { + len = strlen(text); + + if (redraw) + { + if (line_edit) + { + lcd_putc(0, 0, ' '); + lcd_putc(0, 1, KEYBOARD_ARROW); + } + else + { + lcd_putc(0, 0, KEYBOARD_ARROW); + lcd_putc(0, 1, ' '); + } + + /* Draw insert chars */ + temptext[0] = KEYBOARD_INSERT_LEFT; + temptext[1] = line[x%linelen]; + temptext[2] = KEYBOARD_INSERT_RIGHT; + for (i = 1; i < 8; i++) + { + temptext[i+2] = line[(i+x)%linelen]; + } + temptext[i+2] = 0; + lcd_puts(1, 0, temptext); + + /* write out the text */ + curpos = MIN(editpos, 9 - MIN(len - editpos, 2)); + leftpos = editpos - curpos; + strncpy(temptext, text + leftpos, 10); + temptext[10] = 0; + + if (leftpos) + temptext[0] = '<'; + if (len - leftpos > 10) + temptext[9] = '>'; + + lcd_remove_cursor(); + lcd_puts(1, 1, temptext); + lcd_put_cursor(curpos + 1, 1, KEYBOARD_CURSOR); + + status_draw(true); } - temptext[p]=0; - lcd_remove_cursor(); - lcd_puts(1, 0, temptext); - lcd_put_cursor(cursor_pos-left_pos+1, 0, 0x7f); - old_cursor_pos=cursor_pos; - - switch (menu_line) { - case MENU_LINE_INPUT: - case MENU_LINE_NEWCHARS: - /* Draw insert chars */ - temptext[0]=KEYBOARD_INSERT_LEFT; - temptext[1]=line[x%linelen]; - temptext[2]=KEYBOARD_INSERT_RIGHT; - for (i=1; i < 8; i++) { - temptext[i+2]=line[(i+x)%linelen]; - } - temptext[i+2]=0; - lcd_puts(1, 1, temptext); - break; - case MENU_LINE_BACKSPACE: - lcd_puts_scroll(1, 1, str(LANG_PLAYER_KEYBOARD_BACKSPACE)); - break; - case MENU_LINE_DELETE: - lcd_puts_scroll(1, 1, str(LANG_PLAYER_KEYBOARD_DELETE)); + + /* The default action is to redraw */ + redraw = true; + + button = button_get_w_tmo(HZ/2); + switch (button) + { + case BUTTON_STOP: /* abort */ + return -1; break; - case MENU_LINE_ACCEPT: - lcd_puts_scroll(1, 1, str(LANG_PLAYER_KEYBOARD_ACCEPT)); + + case BUTTON_MENU: /* page flip */ + if (++page == KEYBOARD_PAGES) + page = 0; + line = kbd_setupkeys(page, &linelen); + if (x > linelen - 1) + x = linelen - 1; + kbd_spellchar(line[x]); break; - case MENU_LINE_QUIT: - lcd_puts_scroll(1, 1, str(LANG_PLAYER_KEYBOARD_ABORT)); + + case BUTTON_ON: /* toggle mode */ + line_edit = !line_edit; + if (!line_edit) + kbd_spellchar(line[x]); break; - } - if (menu_line==MENU_LINE_INPUT) { - lcd_putc(0, 0, KEYBOARD_ARROW); - lcd_putc(0, 1, ' '); - } else { - lcd_putc(0, 0, ' '); - lcd_putc(0, 1, KEYBOARD_ARROW); - } - - lcd_update(); - button_pressed=button_get(true); - switch (menu_line) - { - case MENU_LINE_INPUT: - switch (button_pressed) + case BUTTON_RIGHT: + case BUTTON_RIGHT | BUTTON_REPEAT: + if (line_edit) { - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - if (cursor_pos0) - cursor_pos--; - button_pressed=BUTTON_NONE; - break; + if (editpos < len) + { + editpos++; + kbd_spellchar(text[editpos]); + } } - break; - - case MENU_LINE_NEWCHARS: - switch (button_pressed) + else { - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - x=(x+1+linelen)%linelen; - button_pressed=BUTTON_NONE; - break; - case BUTTON_STOP: - case BUTTON_STOP | BUTTON_REPEAT: - x=(x-1+linelen)%linelen; - button_pressed=BUTTON_NONE; - break; - - case BUTTON_MENU: - /* shift */ - if (++page == KEYBOARD_PAGES) - page = 0; - line = kbd_setupkeys(page, &linelen); - break; - - case BUTTON_ON: - if (len < buflen) { - /* ON insert the char */ - for (i=len+1; i>cursor_pos; i--) { - text[i]=text[i-1]; - } - text[cursor_pos]=line[x]; - button_pressed=BUTTON_NONE; - cursor_pos++; - } - break; + if (x < linelen - 1) + x++; + else + x = 0; + kbd_spellchar(line[x]); } break; - case MENU_LINE_BACKSPACE: - switch (button_pressed) { - case BUTTON_ON: - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - button_pressed=BUTTON_NONE; - if (0 < cursor_pos) { - for (i=--cursor_pos; i<=len; i++) { - text[i]=text[i+1]; - } - } - break; - case BUTTON_STOP: - case BUTTON_STOP | BUTTON_REPEAT: - button_pressed=BUTTON_NONE; - for (i=cursor_pos; i<=len; i++) { - text[i]=text[i+1]; - } - break; + case BUTTON_LEFT: + case BUTTON_LEFT | BUTTON_REPEAT: + if (line_edit) + { + if (editpos) + { + editpos--; + kbd_spellchar(text[editpos]); + } } - break; - case MENU_LINE_DELETE: - switch (button_pressed) { - case BUTTON_ON: - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - button_pressed=BUTTON_NONE; - for (i=cursor_pos; i<=len; i++) { - text[i]=text[i+1]; - } - break; - case BUTTON_STOP: - case BUTTON_STOP | BUTTON_REPEAT: - button_pressed=BUTTON_NONE; - if (0 < cursor_pos) - for (i=--cursor_pos; i<=len; i++) { - text[i]=text[i+1]; - } - break; + else + { + if (x) + x--; + else + x = linelen - 1; + kbd_spellchar(line[x]); } break; - case MENU_LINE_ACCEPT: - switch (button_pressed) { - case BUTTON_ON: - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - button_pressed=BUTTON_NONE; - done=true; - break; - } + case BUTTON_PLAY | BUTTON_REPEAT: + /* accepts what was entered and continues */ + done = true; break; - case MENU_LINE_QUIT: - switch (button_pressed) { - case BUTTON_ON: - case BUTTON_PLAY: - case BUTTON_PLAY | BUTTON_REPEAT: - return 1; - break; + case BUTTON_PLAY | BUTTON_REL: + if (lastbutton != BUTTON_PLAY) + break; + if (line_edit) /* backspace in line_edit */ + { + if (editpos > 0) + { + for (i = editpos; i < len; i++) + text[i-1] = text[i]; + text[i-1] = '\0'; + editpos--; + } } + else /* inserts the selected char */ + { + if (len < buflen) + { + c = line[x]; + if (editpos == len) + { + text[len] = c; + text[len+1] = 0; + } + else + { + for (i = len ; i >= editpos; i--) + text[i+1] = text[i]; + text[editpos] = c; + } + editpos++; + } + } + if (global_settings.talk_menu) /* voice UI? */ + talk_spell(text, false); /* speak revised text */ break; - } - /* Handle unhandled events */ - switch (button_pressed) { case BUTTON_NONE: - /* button is already handled */ + status_draw(false); + redraw = false; break; - case BUTTON_MENU | BUTTON_STOP: - break; - - case BUTTON_RIGHT: - case BUTTON_RIGHT | BUTTON_REPEAT: - if (menu_line0) - menu_line--; - else - menu_line=MENU_LINE_LAST; + default: + default_event_handler(button); break; } + if (button != BUTTON_NONE) + lastbutton = button; } - + return 0; } + -- cgit v1.2.3