summaryrefslogtreecommitdiff
path: root/apps/player/keyboard.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-02-06 23:23:49 +0000
committerJens Arnold <amiconn@rockbox.org>2005-02-06 23:23:49 +0000
commit5c55e7f8ad442b1f9c4617bff6a4fff2ee25fdf1 (patch)
treecd571400964dd08c96d32463166cfd13710c7385 /apps/player/keyboard.c
parenta83ffb208f53a91aeab09b933e3544ec29919ce1 (diff)
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
Diffstat (limited to 'apps/player/keyboard.c')
-rw-r--r--apps/player/keyboard.c422
1 files changed, 188 insertions, 234 deletions
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 <string.h>
#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<cursor_pos)
- left_pos=cursor_pos-9;
-
- while (!done) {
- int i, p;
- int len = strlen(text);
- int scrpos;
- int dir;
-
- scrpos = cursor_pos - left_pos;
- dir = cursor_pos - old_cursor_pos;
-
- /* Keep the cursor on screen, with a 2 character scroll margin */
- if(dir < 0) {
- if(scrpos < 2) {
- left_pos = cursor_pos - 2;
- if(left_pos < 0)
- left_pos = 0;
- }
- }
- if(dir > 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_pos<len)
- cursor_pos++;
- button_pressed=BUTTON_NONE;
- break;
-
- case BUTTON_STOP:
- case BUTTON_STOP | BUTTON_REPEAT:
- if (cursor_pos>0)
- 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_line<MENU_LINE_LAST)
- menu_line++;
- else
- menu_line=0;
- break;
-
- case BUTTON_LEFT:
- case BUTTON_LEFT | BUTTON_REPEAT:
- if (menu_line>0)
- menu_line--;
- else
- menu_line=MENU_LINE_LAST;
+ default:
+ default_event_handler(button);
break;
}
+ if (button != BUTTON_NONE)
+ lastbutton = button;
}
-
+
return 0;
}
+