Recently, I had to program a device that had only a numeric keypad for some light data entry. The manufacturer had a relatively cumbersome method for entering text and I had to come up with an alternative means to more conveniently enter text using the numeric keypad.
The application did not require mixed case characters, so I decided to limit data entry to uppercase characters to reduce the number of keystrokes required. Unlike typical mobile phone input, there is no timeout for the next character to be entered. Adding this is not hard at all, and would probably only require about three to five extra lines of code ...
void succ(int* ip, char* cp, char* ch)
{
int il = strlen(ch);
char *np;
if(*(cp + *ip) == '\0') {
*(cp + *ip) = *ch;
return;
}
np = strchr(ch, *(cp + *ip));
if(np == NULL) {
(*ip)++;
*(cp + *ip) = *ch;
} else if(np == ch + il - 1) {
*(cp + *ip) = *ch;
} else {
*(cp + *ip) = *(np + 1);
}
}
int textual_input(int line, char *destination, int maxlen)
{
int nKey, i = 0;
char text[128];
memset(text, 0, sizeof(text));
while(1)
{
nKey = Sys_Key_WaitKey();
switch (nKey)
{
case KEY_DEL: text[i] = '\0'; i > 0 ? i-- : i = 0; break;
case KEY_0: i++; text[i] = ' '; break;
case KEY_1: i++; break;
case KEY_2: succ(&i, text, "ABC"); break;
case KEY_3: succ(&i, text, "DEF"); break;
case KEY_4: succ(&i, text, "GHI"); break;
case KEY_5: succ(&i, text, "JKL"); break;
case KEY_6: succ(&i, text, "MNO"); break;
case KEY_7: succ(&i, text, "PQRS"); break;
case KEY_8: succ(&i, text, "TUV"); break;
case KEY_9: succ(&i, text, "WXYZ"); break;
case KEY_ENTER: goto done; break;
case KEY_CANCEL: goto cancel; break;
}
Syd_ClearWindow(line,line);
Syd_DisplayLine(line, text, 0, ALIGN_LEFT );
}
done:
strncpy(destination, text, maxlen);
return 0;
cancel:
memset(destination, 0, maxlen);
return -1;
}
I hope someone finds this code useful. It's not a huge piece of code, not hard to understand and is also small enough to maintain. As always, I love to hear of better ways to do things so any suggestions are welcome!