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:
- 0:9b0b4ae5b47a
- Child:
- 1:7feeebbd8367
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Keypad.cpp Mon Feb 08 02:38:43 2016 +0000 @@ -0,0 +1,215 @@ +#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[] = { + 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, + 5,'\x01',21,'\x18',10,'Z',10,'X',10,'C',10,'V',10,'B',10,'N',10,'M',10,'<',10,'>',10,'?',21,'\x18',0,0, + 5,'\x01',40,'\x01',55,' ',0,0, + 0,0 +}; +const char 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, + 5,'\x01',21,'\x18',10,'z',10,'x',10,'c',10,'v',10,'b',10,'n',10,'m',10,',',10,'.',10,'/',21,'\x18',0,0, + 5,'\x01',40,'\x01',55,' ',0,0, + 0,0 +}; + + +Keypad::Keypad(RA8875 & _ra, color_t _fore, color_t _back) : ra(_ra), fore(_fore), back(_back) { + shift = false; +} + +Keypad::~Keypad() { +} + +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); + ra.putc(c); +} + +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; + ra.fillrect(r, c); +} + +void Keypad::DrawInputPanel(const char * prompt) { + 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; + + 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(); +} + +void Keypad::DrawKeypad(void) { + dim_t fW = ra.fontwidth(); + dim_t fH = ra.fontheight(); + dim_t kW = ra.width() / (cols+1); + 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; + + if (shift) + p = shiftkeys; + while (*p || *(p+2)) { + if (*p == 0) { + r.p1.x = 0; + r.p1.y += kH; + } else { + const char * symbol = p + 1; + if (*symbol >= 0x10) { + r.p2.x = r.p1.x + (kW * *p)/10; + r.p2.y = r.p1.y + kH; + DrawKey(r,*symbol); + } + r.p1.x += (kW * *p)/10; + } + p+=2; + } +} + +char Keypad::isKeyTouched(point_t * point, rect_t * rectTouched) { + dim_t kW = ra.width() / (cols+1); + 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; + + if (shift) + p = shiftkeys; + while (*p || *(p+2)) { + if (*p == 0) { + r.p1.x = 0; + r.p1.y += kH; + } else { + const char * symbol = p + 1; + if (*symbol >= 0x10) { + r.p2.x = r.p1.x + (kW * *p)/10; + r.p2.y = r.p1.y + kH; + if (ra.Intersect(r, *point)) { + if (rectTouched) + *rectTouched = r; + return (*symbol); + } + } + r.p1.x += (kW * *p)/10; + } + p+=2; + } + return 0; +} + +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()); + ra.SetTextCursor(userText.x, userText.y); + ra.SetTextCursorControl(RA8875::UNDER); +} + +bool Keypad::GetString(char * buffer, size_t size, const char * prompt, char mask) { + point_t point = {0, 0}; + + pStart = pNext = buffer; + bufSize = size; + DrawInputPanel(prompt); + ShowBufferMetrics(); + while (1) { + if (touch == ra.TouchPanelReadable(&point)) { + rect_t touchRect; + // find out of they touched a key; + char key = isKeyTouched(&point, &touchRect); + if (key) { + DrawKey(touchRect, key, true); + wait_ms(50); + TouchCode_t is; + do { + is = ra.TouchPanelReadable(NULL); + 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) { + *pNext = '\0'; + ra.SetTextCursorControl(); + return true; + } else if (key == KEY_ESC) { + *buffer = '\0'; + ra.SetTextCursorControl(); + return false; + } else if (key == KEY_BS) { + if (pNext > buffer) { + pNext--; + // blank the last char + userText.x -= ra.fontwidth(); + ra.SetTextCursor(userText.x, userText.y); + ra.putc(' '); + } + } else if (key == KEY_TAB) { + *pNext++ = ' '; + ra.SetTextCursor(userText.x, userText.y); + ra.putc(' '); + userText.x += ra.fontwidth(); + } else if (key == KEY_SHIFT) { + shift = !shift; + DrawKeypad(); + } else if (key) { + *pNext++ = key; + ra.SetTextCursor(userText.x, userText.y); + if (mask) + ra.putc(mask); + else + ra.putc(key); + userText.x += ra.fontwidth(); + } + if ((pNext - buffer) >= (size - 1)) { + *pNext = '\0'; + ra.SetTextCursorControl(); + return true; + } + ShowBufferMetrics(); + } + } +}