Onscreen QWERTY keypad for RA8857 based display. Uses the resistive touch panel.
Dependents: RA8875_KeyPadDemo PUB_RA8875_Keypad IAC_Final_Monil_copy
Keypad.cpp
- Committer:
- WiredHome
- Date:
- 2016-03-05
- Revision:
- 2:6d05764dfde7
- Parent:
- 1:7feeebbd8367
- Child:
- 3:402f1126a3ec
File content as of revision 2:6d05764dfde7:
#include "Keypad.h" // 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 kpd_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 kpd_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 }; 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 kpd_unshiftkeys, kpd_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.fillroundrect(r, 2, 2, invert ? fore : back); ra.roundrect(r, 2, 2, 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 = ComputeKeypadRect(); ra.fillrect(r, c); } void Keypad::DrawInputPanel(const char * prompt) { dim_t kH = ra.fontheight() + 4; rect_t r = ComputeKeypadRect(); 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(); 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; dim_t kH = fH + 4; const char * p = kbd->keydef1; rect_t r = ComputeKeypadRect(); rect_t ref = r; kW = (ref.p2.x - ref.p1.x) / (kbd->cols+1); printf("DrawKeypad kW=%d from (%d,%d) %d\r\n", kW, ref.p2.x, ref.p1.x, kbd->cols+1); r.p1.y += kH; if (shift) p = kbd->keydef2; while (*p || *(p+2)) { if (*p == 0) { r.p1.x = ref.p1.x; 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; dim_t kH = ra.fontheight() + 4; 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 = kbd->keydef2; while (*p || *(p+2)) { if (*p == 0) { r.p1.x = ref.p1.x; 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) { 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); } 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 if 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 == enter_key) { *pNext = '\0'; ra.SetTextCursorControl(); return true; } else if (key == esc_key) { *buffer = '\0'; ra.SetTextCursorControl(); return false; } else if (key == KYBD_SYM_BS) { if (pNext > buffer) { pNext--; // blank the last char userText.x -= ra.fontwidth(); ra.SetTextCursor(userText.x, userText.y); ra.putc(' '); } } else if (key == KYBD_SYM_TAB) { *pNext++ = ' '; ra.SetTextCursor(userText.x, userText.y); ra.putc(' '); userText.x += ra.fontwidth(); } else if (key == KYBD_SYM_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(); } } } const Keypad::keyboard_t * Keypad::GetInternalKeypad(void) { return &internalkbd; }