Onscreen QWERTY keypad for RA8857 based display. Uses the resistive touch panel.
Dependents: RA8875_KeyPadDemo PUB_RA8875_Keypad IAC_Final_Monil_copy
Diff: Keypad.cpp
- Revision:
- 1:7feeebbd8367
- Parent:
- 0:9b0b4ae5b47a
- Child:
- 2:6d05764dfde7
--- a/Keypad.cpp Mon Feb 08 02:38:43 2016 +0000 +++ b/Keypad.cpp Fri Mar 04 12:23:44 2016 +0000 @@ -1,16 +1,11 @@ #include "Keypad.h" -#define KROWS 5 -// OK, these key assignments are a bit odd looking. The value are mapped to the character set of the RA8875 -// internal font. The selected characters shown various symbols - left arrow for the <bs>, up arrow for <shift> -// and so on. They then have to be mapped to legitimate characters as needed. -#define KEY_SHIFT 0x18 -#define KEY_TAB 0x1A -#define KEY_CR 0x1C -#define KEY_BS 0x1B -#define KEY_ESC 0x15 -const int cols = 15; -const char shiftkeys[] = { +// byte pairs: size, symbol [,size, symbol [, size, symbol [...]]] +// size is a scale factor where 10 = "normal calculated size" based on the keyboard width and the # of keys, 5 is 1/2 width, etc. +// symbol is either the ASCII character to show, when leveraging the RA8875 internal fonts, or it is a special +// character [normally non-printable] that is intercepted to perform an operation (e.g. <bs>, <shift>, etc.) +// \x01: special no-key value, to leave whitespace before the next key. +const char p_shiftkeys[] = { 5,'\x01', 8,'\x15',10,'~',10,'!',10,'@',10,'#',10,'$',10,'%',10,'^',10,'&',10,'*',10,'(',10,')',10,'_', 10,'+',10,'\x1B',0,0, 5,'\x01',12,'\x1A',10,'Q',10,'W',10,'E',10,'R',10,'T',10,'Y',10,'U',10,'I',10,'O',10,'P',10,'{', 10,'}',10,'|',0,0, 5,'\x01',15,' ',10,'A',10,'S',10,'D',10,'F',10,'G',10,'H',10,'J',10,'K',10,'L',10,':',10,'"', 17,'\x1C',0,0, @@ -18,7 +13,7 @@ 5,'\x01',40,'\x01',55,' ',0,0, 0,0 }; -const char unshiftkeys[] = { +const char p_unshiftkeys[] = { 5,'\x01', 8,'\x15',10,'`',10,'1',10,'2',10,'3',10,'4',10,'5',10,'6',10,'7',10,'8',10,'9',10,'0',10,'-', 10,'=',10,'\x1B',0,0, 5,'\x01',12,'\x1A',10,'q',10,'w',10,'e',10,'r',10,'t',10,'y',10,'u',10,'i',10,'o',10,'p',10,'[', 10,']',10,'\\',0,0, 5,'\x01',15,' ',10,'a',10,'s',10,'d',10,'f',10,'g',10,'h',10,'j',10,'k',10,'l',10,';',10,'\'', 17,'\x1C',0,0, @@ -27,69 +22,113 @@ 0,0 }; +const Keypad::keyboard_t internalkbd = { + 0,-1, // x,y: 0; start at left edge, -1; top is calculated from # rows + // -1 is size calculated + 0, // wi,h: width is calculated + 0, // bottom of screen justified + 5, // 5 rows + 15, // columns in the <esc>`1234...-=<bs> row + p_unshiftkeys, + p_shiftkeys +}; + + Keypad::Keypad(RA8875 & _ra, color_t _fore, color_t _back) : ra(_ra), fore(_fore), back(_back) { shift = false; + enter_key = KYBD_SYM_ENTER; + esc_key = KYBD_SYM_ESCAPE; } Keypad::~Keypad() { } +bool Keypad::SetKeyboard(const keyboard_t * _kbd, char _enter_key, char _esc_key) { + if (_kbd) + kbd = _kbd; + else + kbd = &internalkbd; + enter_key = _enter_key; + esc_key = _esc_key; + return true; +} + void Keypad::DrawKey(rect_t r, char c, bool invert) { ra.fillrect(r, invert ? fore : back); ra.rect(r, invert ? back : fore); ra.SetTextCursor(r.p1.x+(r.p2.x-r.p1.x)/2-ra.fontwidth()/2, r.p1.y+2); + if (invert) { + ra.foreground(back); + ra.background(fore); + } ra.putc(c); + if (invert) { + ra.foreground(fore); + ra.background(back); + } } void Keypad::Erase(color_t c) { dim_t kH = ra.fontheight() + 4; - rect_t r; - - r.p1.x = 0; - r.p1.y = ra.height() - (kH * (KROWS+1)) - 1; - r.p2.x = ra.width() - 1; - r.p2.y = ra.height() - 1; + rect_t r = ComputeKeypadRect(); + ra.fillrect(r, c); } void Keypad::DrawInputPanel(const char * prompt) { dim_t kH = ra.fontheight() + 4; - rect_t r; + rect_t r = ComputeKeypadRect(); - r.p1.x = 0; - r.p1.y = ra.height() - (kH * (KROWS+1)) - 1; - r.p2.x = ra.width() - 1; - r.p2.y = ra.height() - 1; - ra.fillrect(r, back); ra.foreground(fore); ra.background(back); ra.SetTextCursor(r.p1.x,r.p1.y+2); ra.puts(prompt); userText = ra.GetTextCursor(); - r.p1.y += kH; DrawKeypad(); } +rect_t Keypad::ComputeKeypadRect(void) { + dim_t kH = ra.fontheight() + 4; + rect_t r; + + if (kbd->x <= 0) + r.p1.x = 0; + else + r.p1.x = kbd->x; + if (kbd->y <= 0) + r.p1.y = ra.height() - (kH * (kbd->rows+1)) - 1; + else + r.p1.y = kbd->y; + if (kbd->width == 0) + r.p2.x = ra.width() - 1; + else + r.p2.x = r.p1.x + kbd->width - 1; + if (kbd->height == 0) + r.p2.y = ra.height() - 1; + else + r.p2.y = r.p1.y + kbd->height - 1; + printf("KeypadRect (%d,%d) - (%d,%d)\r\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y); + return r; +} + void Keypad::DrawKeypad(void) { dim_t fW = ra.fontwidth(); dim_t fH = ra.fontheight(); - dim_t kW = ra.width() / (cols+1); + dim_t kW; dim_t kH = fH + 4; - const char * p = unshiftkeys; - rect_t r; - - r.p1.x = 0; - r.p1.y = ra.height() - (kH * (KROWS+1)) - 1 + kH; - r.p2.x = ra.width() - 1; - r.p2.y = ra.height() - 1; - + + const char * p = kbd->keydef1; + rect_t r = ComputeKeypadRect(); + rect_t ref = r; + kW = (ref.p2.x - ref.p1.x) / (kbd->cols+1); + r.p1.y += kH; if (shift) - p = shiftkeys; + p = kbd->keydef2; while (*p || *(p+2)) { if (*p == 0) { - r.p1.x = 0; + r.p1.x = ref.p1.x; r.p1.y += kH; } else { const char * symbol = p + 1; @@ -105,21 +144,19 @@ } char Keypad::isKeyTouched(point_t * point, rect_t * rectTouched) { - dim_t kW = ra.width() / (cols+1); + dim_t kW; dim_t kH = ra.fontheight() + 4; - rect_t r; - const char * p = unshiftkeys; - - r.p1.x = 0; - r.p1.y = ra.height() - (kH * (KROWS+1)) - 1 + kH; - r.p2.x = ra.width() - 1; - r.p2.y = ra.height() - 1; + const char * p = kbd->keydef1; + rect_t r = ComputeKeypadRect(); + rect_t ref = r; + kW = (ref.p2.x - ref.p1.x) / (kbd->cols+1); + r.p1.y = r.p1.y + kH; if (shift) - p = shiftkeys; + p = kbd->keydef2; while (*p || *(p+2)) { if (*p == 0) { - r.p1.x = 0; + r.p1.x = ref.p1.x; r.p1.y += kH; } else { const char * symbol = p + 1; @@ -140,10 +177,10 @@ } void Keypad::ShowBufferMetrics(void) { - // "001/100" - ra.SetTextCursor(ra.width()-1-ra.fontwidth()*7, ra.height()-1-ra.fontheight()); - ra.printf("%03d/%03d", pNext - pStart, bufSize); - ra.SetTextCursor(ra.width()-1-ra.fontwidth()*7, ra.height()-1-ra.fontheight()); + rect_t r = ComputeKeypadRect(); + ra.SetTextCursor(r.p2.x-1-ra.fontwidth()*7, r.p1.y+2); + ra.printf("%03d/%03d", pNext - pStart, bufSize); // "001/100" + //ra.SetTextCursor(ra.width()-1-ra.fontwidth()*7, ra.height()-1-ra.fontheight()); ra.SetTextCursor(userText.x, userText.y); ra.SetTextCursorControl(RA8875::UNDER); } @@ -158,7 +195,7 @@ while (1) { if (touch == ra.TouchPanelReadable(&point)) { rect_t touchRect; - // find out of they touched a key; + // find out if they touched a key; char key = isKeyTouched(&point, &touchRect); if (key) { DrawKey(touchRect, key, true); @@ -166,20 +203,20 @@ TouchCode_t is; do { is = ra.TouchPanelReadable(NULL); - printf("is: %d\r\n", is); + //printf("is: %d\r\n", is); } while (is != no_touch); DrawKey(touchRect, key); } printf("Touch %02X at (%d,%d)\r\n", key, point.x, point.y); - if (key == KEY_CR) { + if (key == enter_key) { *pNext = '\0'; ra.SetTextCursorControl(); return true; - } else if (key == KEY_ESC) { + } else if (key == esc_key) { *buffer = '\0'; ra.SetTextCursorControl(); return false; - } else if (key == KEY_BS) { + } else if (key == KYBD_SYM_BS) { if (pNext > buffer) { pNext--; // blank the last char @@ -187,12 +224,12 @@ ra.SetTextCursor(userText.x, userText.y); ra.putc(' '); } - } else if (key == KEY_TAB) { + } else if (key == KYBD_SYM_TAB) { *pNext++ = ' '; ra.SetTextCursor(userText.x, userText.y); ra.putc(' '); userText.x += ra.fontwidth(); - } else if (key == KEY_SHIFT) { + } else if (key == KYBD_SYM_SHIFT) { shift = !shift; DrawKeypad(); } else if (key) {