blob: 32a1d8b735e1faf24cfe8979d5e539d7e75b6174 [file] [log] [blame]
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "lcd.h"
20#include "button.h"
21#include "kernel.h"
22#include "version.h"
23#include "debug_menu.h"
24#include "sprintf.h"
25#include <string.h>
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000026#include "font.h"
Björn Stenbergaa2972d2003-03-10 15:09:27 +000027#include "screens.h"
Linus Nielsen Feltzing6afd0a72003-11-04 12:36:55 +000028#include "status.h"
Jörg Hohensohn9e049572004-05-21 06:29:55 +000029#include "talk.h"
30#include "settings.h"
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000031
32#define KEYBOARD_LINES 4
33#define KEYBOARD_PAGES 3
34
35static void kbd_setupkeys(char* line[KEYBOARD_LINES], int page)
36{
37 switch (page) {
38 case 0:
39 line[0] = "ABCDEFG !?\" @#$%+'";
40 line[1] = "HIJKLMN 789 &_()-`";
41 line[2] = "OPQRSTU 456 §|{}/<";
42 line[3] = "VWXYZ.,0123 ~=[]*>";
43 break;
44
45 case 1:
46 line[0] = "abcdefg ¢£¤¥¦§©®¬";
47 line[1] = "hijklmn «»°ºª¹²³¶";
Björn Stenberg43d6d282003-01-15 14:31:05 +000048 line[2] = "opqrstu ¯±×÷¡¿µ·¨";
Björn Stenbergaa2972d2003-03-10 15:09:27 +000049 line[3] = "vwxyz., ¼½¾ ";
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000050 break;
51
52 case 2:
53 line[0] = "ÀÁÂÃÄÅÆ ÌÍÎÏ ÈÉÊË";
54 line[1] = "àáâãäåæ ìíîï èéêë";
55 line[2] = "ÓÒÔÕÖØ ÇÐÞÝß ÙÚÛÜ";
56 line[3] = "òóôõöø çðþýÿ ùúûü";
57 break;
58 }
59}
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +000060
Jörg Hohensohn9e049572004-05-21 06:29:55 +000061/* helper function to spell a char if voice UI is enabled */
62void kbd_spellchar(char c)
63{
64 char spell_char[2]; /* store char to pass to talk_spell */
65
66 if (global_settings.talk_menu) /* voice UI? */
67 {
68 spell_char[0] = c;
69 spell_char[1] = '\0'; /* mark end of char string */
70
71 talk_spell(spell_char, false);
72 }
73}
74
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000075int kbd_input(char* text, int buflen)
76{
77 bool done = false;
78 int page = 0;
79
80 int font_w = 0, font_h = 0, i;
81 int x = 0, y = 0;
82 int main_x, main_y, max_chars, margin;
83 int status_y1, status_y2, curpos;
84 int len;
Björn Stenbergaa2972d2003-03-10 15:09:27 +000085 int editpos;
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +000086 bool redraw = true;
Björn Stenbergaa2972d2003-03-10 15:09:27 +000087 char* line[KEYBOARD_LINES];
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000088
Björn Stenbergaa2972d2003-03-10 15:09:27 +000089 char outline[256];
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000090 char c = 0;
91 struct font* font = font_get(FONT_SYSFIXED);
92
Björn Stenberg58dff172003-01-15 13:48:54 +000093 lcd_setfont(FONT_SYSFIXED);
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000094 font_w = font->maxwidth;
95 font_h = font->height;
96
97 margin = 3;
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +000098 main_y = (KEYBOARD_LINES + 1) * font_h + margin*2;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +000099 main_x = 0;
100 status_y1 = LCD_HEIGHT - font_h;
101 status_y2 = LCD_HEIGHT;
102
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000103 editpos = strlen(text);
104
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000105 max_chars = LCD_WIDTH / font_w;
106 kbd_setupkeys(line, page);
107
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000108 if (global_settings.talk_menu) /* voice UI? */
109 talk_spell(text, true); /* spell initial text */
110
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000111 while(!done)
112 {
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000113 len = strlen(text);
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000114
115 if(redraw)
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000116 {
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000117 lcd_clear_display();
118
119 lcd_setfont(FONT_SYSFIXED);
120
121 /* draw page */
122 for (i=0; i < KEYBOARD_LINES; i++)
123 lcd_putsxy(0, 8+i * font_h, line[i]);
124
125 /* separator */
126 lcd_drawline(0, main_y - margin, LCD_WIDTH, main_y - margin);
127
128 /* write out the text */
129 if (editpos < max_chars - 3 )
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000130 {
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000131 strncpy(outline, text, max_chars - 2);
132 if (len > max_chars - 2)
133 lcd_putsxy(LCD_WIDTH - font_w, main_y, ">");
134 curpos = (1 + editpos) * font_w;
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000135 }
136 else
137 {
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000138 /* not room for all text, cut left, right or both */
139 if (editpos == len )
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000140 {
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000141 if ( max_chars - 3 == len)
142 {
143 strncpy(outline, text, max_chars - 2);
144 curpos = (1 + editpos) * font_w;
145 }
146 else
147 {
148 strncpy(outline, text + editpos - max_chars + 2,
149 max_chars - 2);
150 if (len > max_chars - 2)
151 lcd_putsxy(0, main_y, "<");
152 curpos = ( max_chars - 1) * font_w;
153 }
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000154 }
155 else
156 {
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000157 if (len - 1 == editpos)
158 {
159 strncpy(outline, text + editpos - max_chars + 3,
160 max_chars - 2);
161 curpos = ( max_chars - 2) * font_w;
162 }
163 else
164 {
165 strncpy(outline, text + editpos - max_chars + 4,
166 max_chars - 2);
167 curpos = ( max_chars - 3) * font_w;
168 }
169 lcd_putsxy(LCD_WIDTH - font_w, main_y, ">");
170 lcd_putsxy(0, main_y, "<");
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000171 }
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000172 }
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000173
174 /* Zero terminate the string */
175 outline[max_chars - 2] = '\0';
176
177 lcd_putsxy(font_w,main_y,outline);
178
179 /* cursor */
180 lcd_drawline(curpos, main_y, curpos, main_y + font_h);
181
182 /* draw the status bar */
183 buttonbar_set("Shift", "OK", "Del");
184 buttonbar_draw();
185
186 /* highlight the key that has focus */
187 lcd_invertrect(font_w * x, 8 + font_h * y, font_w, font_h);
188
189 status_draw(true);
190
191 lcd_update();
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000192 }
193
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000194 /* The default action is to redraw */
195 redraw = true;
Linus Nielsen Feltzing55fc6df2003-03-17 23:16:20 +0000196
Linus Nielsen Feltzing6afd0a72003-11-04 12:36:55 +0000197 switch ( button_get_w_tmo(HZ/2) ) {
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000198
Björn Stenberg58dff172003-01-15 13:48:54 +0000199 case BUTTON_OFF:
Björn Stenberg58dff172003-01-15 13:48:54 +0000200 /* abort */
201 lcd_setfont(FONT_UI);
202 return -1;
203 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000204
Björn Stenberg58dff172003-01-15 13:48:54 +0000205 case BUTTON_F1:
206 /* Page */
207 if (++page == KEYBOARD_PAGES)
208 page = 0;
209 kbd_setupkeys(line, page);
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000210 kbd_spellchar(line[y][x]);
Björn Stenberg58dff172003-01-15 13:48:54 +0000211 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000212
Björn Stenberg58dff172003-01-15 13:48:54 +0000213 case BUTTON_RIGHT:
214 case BUTTON_RIGHT | BUTTON_REPEAT:
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000215 if (x < (int)strlen(line[y]) - 1)
216 x++;
217 else
Björn Stenberg58dff172003-01-15 13:48:54 +0000218 x = 0;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000219 kbd_spellchar(line[y][x]);
Björn Stenberg58dff172003-01-15 13:48:54 +0000220 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000221
Björn Stenberg58dff172003-01-15 13:48:54 +0000222 case BUTTON_LEFT:
223 case BUTTON_LEFT | BUTTON_REPEAT:
224 if (x)
225 x--;
226 else
227 x = strlen(line[y]) - 1;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000228 kbd_spellchar(line[y][x]);
Björn Stenberg58dff172003-01-15 13:48:54 +0000229 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000230
Björn Stenberg58dff172003-01-15 13:48:54 +0000231 case BUTTON_DOWN:
232 case BUTTON_DOWN | BUTTON_REPEAT:
233 if (y < KEYBOARD_LINES - 1)
234 y++;
235 else
236 y=0;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000237 kbd_spellchar(line[y][x]);
Björn Stenberg58dff172003-01-15 13:48:54 +0000238 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000239
Björn Stenberg58dff172003-01-15 13:48:54 +0000240 case BUTTON_UP:
241 case BUTTON_UP | BUTTON_REPEAT:
242 if (y)
243 y--;
244 else
245 y = KEYBOARD_LINES - 1;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000246 kbd_spellchar(line[y][x]);
Björn Stenberg58dff172003-01-15 13:48:54 +0000247 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000248
Björn Stenberg58dff172003-01-15 13:48:54 +0000249 case BUTTON_F3:
Björn Stenberg34c17952003-01-18 17:47:50 +0000250 case BUTTON_F3 | BUTTON_REPEAT:
Björn Stenberg58dff172003-01-15 13:48:54 +0000251 /* backspace */
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000252 if (editpos > 0)
253 {
254 for (i = editpos; i <= (len - 1);i++)
255 {
256 text[i-1] = text[i];
257 }
258 text[i-1]='\0';
259 editpos--;
260 if (editpos < 0)
261 editpos=0;
262 }
Björn Stenberg58dff172003-01-15 13:48:54 +0000263 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000264
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000265 case BUTTON_F2:
266 /* F2 accepts what was entered and continues */
Björn Stenberg58dff172003-01-15 13:48:54 +0000267 done = true;
268 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000269
Björn Stenberg58dff172003-01-15 13:48:54 +0000270 case BUTTON_PLAY:
271 /* PLAY inserts the selected char */
272 if (len<buflen)
273 {
274 c = line[y][x];
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000275 if ( editpos == len )
276 {
277 text[len] = c;
278 text[len+1] = 0;
279 }
280 else
281 {
282 for (i = len ; i + 1 > editpos; i--)
283 text[i+1] = text[i];
284 text[editpos] = c;
285 }
286 editpos++;
Björn Stenberg58dff172003-01-15 13:48:54 +0000287 }
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000288 if (global_settings.talk_menu) /* voice UI? */
289 talk_spell(text, false); /* speak revised text */
Björn Stenberg58dff172003-01-15 13:48:54 +0000290 break;
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000291
292 case BUTTON_ON | BUTTON_RIGHT:
293 case BUTTON_ON | BUTTON_RIGHT | BUTTON_REPEAT:
294 /* moved cursor right */
295 editpos++;
296 if (editpos > len)
297 editpos = len;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000298 else
299 kbd_spellchar(text[editpos]);
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000300 break;
301
302 case BUTTON_ON | BUTTON_LEFT:
303 case BUTTON_ON | BUTTON_LEFT | BUTTON_REPEAT:
304 /* moved cursor left */
305 editpos--;
306 if (editpos < 0)
307 editpos = 0;
Jörg Hohensohn9e049572004-05-21 06:29:55 +0000308 else
309 kbd_spellchar(text[editpos]);
Björn Stenbergaa2972d2003-03-10 15:09:27 +0000310 break;
311
312 case SYS_USB_CONNECTED:
313 usb_screen();
314 lcd_setfont(FONT_SYSFIXED);
315 break;
Linus Nielsen Feltzing6afd0a72003-11-04 12:36:55 +0000316
317 case BUTTON_NONE:
318 status_draw(false);
Linus Nielsen Feltzing210de712003-11-17 02:10:09 +0000319 redraw = false;
Linus Nielsen Feltzing6afd0a72003-11-04 12:36:55 +0000320 break;
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000321 }
322 }
Björn Stenberg58dff172003-01-15 13:48:54 +0000323 lcd_setfont(FONT_UI);
Björn Stenbergc8cb6ff2002-12-04 15:04:43 +0000324 return 0;
325}