Onscreen QWERTY keypad for RA8857 based display. Uses the resistive touch panel.

Dependents:   RA8875_KeyPadDemo PUB_RA8875_Keypad IAC_Final_Monil_copy

Committer:
WiredHome
Date:
Sat Mar 05 16:47:58 2016 +0000
Revision:
3:402f1126a3ec
Parent:
2:6d05764dfde7
Child:
4:edb5155f1b6f
Remove some debug print statements, also hide the cursor while touching a key.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:9b0b4ae5b47a 1 #include "Keypad.h"
WiredHome 0:9b0b4ae5b47a 2
WiredHome 1:7feeebbd8367 3 // byte pairs: size, symbol [,size, symbol [, size, symbol [...]]]
WiredHome 1:7feeebbd8367 4 // 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.
WiredHome 1:7feeebbd8367 5 // symbol is either the ASCII character to show, when leveraging the RA8875 internal fonts, or it is a special
WiredHome 1:7feeebbd8367 6 // character [normally non-printable] that is intercepted to perform an operation (e.g. <bs>, <shift>, etc.)
WiredHome 1:7feeebbd8367 7 // \x01: special no-key value, to leave whitespace before the next key.
WiredHome 2:6d05764dfde7 8 const char kpd_shiftkeys[] = {
WiredHome 0:9b0b4ae5b47a 9 5,'\x01', 8,'\x15',10,'~',10,'!',10,'@',10,'#',10,'$',10,'%',10,'^',10,'&',10,'*',10,'(',10,')',10,'_', 10,'+',10,'\x1B',0,0,
WiredHome 0:9b0b4ae5b47a 10 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,
WiredHome 0:9b0b4ae5b47a 11 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,
WiredHome 0:9b0b4ae5b47a 12 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,
WiredHome 0:9b0b4ae5b47a 13 5,'\x01',40,'\x01',55,' ',0,0,
WiredHome 0:9b0b4ae5b47a 14 0,0
WiredHome 0:9b0b4ae5b47a 15 };
WiredHome 2:6d05764dfde7 16 const char kpd_unshiftkeys[] = {
WiredHome 0:9b0b4ae5b47a 17 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,
WiredHome 0:9b0b4ae5b47a 18 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,
WiredHome 0:9b0b4ae5b47a 19 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,
WiredHome 0:9b0b4ae5b47a 20 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,
WiredHome 0:9b0b4ae5b47a 21 5,'\x01',40,'\x01',55,' ',0,0,
WiredHome 0:9b0b4ae5b47a 22 0,0
WiredHome 0:9b0b4ae5b47a 23 };
WiredHome 0:9b0b4ae5b47a 24
WiredHome 1:7feeebbd8367 25 const Keypad::keyboard_t internalkbd = {
WiredHome 1:7feeebbd8367 26 0,-1, // x,y: 0; start at left edge, -1; top is calculated from # rows
WiredHome 1:7feeebbd8367 27 // -1 is size calculated
WiredHome 1:7feeebbd8367 28 0, // wi,h: width is calculated
WiredHome 1:7feeebbd8367 29 0, // bottom of screen justified
WiredHome 1:7feeebbd8367 30 5, // 5 rows
WiredHome 1:7feeebbd8367 31 15, // columns in the <esc>`1234...-=<bs> row
WiredHome 2:6d05764dfde7 32 kpd_unshiftkeys,
WiredHome 2:6d05764dfde7 33 kpd_shiftkeys
WiredHome 1:7feeebbd8367 34 };
WiredHome 1:7feeebbd8367 35
WiredHome 1:7feeebbd8367 36
WiredHome 0:9b0b4ae5b47a 37
WiredHome 0:9b0b4ae5b47a 38 Keypad::Keypad(RA8875 & _ra, color_t _fore, color_t _back) : ra(_ra), fore(_fore), back(_back) {
WiredHome 0:9b0b4ae5b47a 39 shift = false;
WiredHome 1:7feeebbd8367 40 enter_key = KYBD_SYM_ENTER;
WiredHome 1:7feeebbd8367 41 esc_key = KYBD_SYM_ESCAPE;
WiredHome 0:9b0b4ae5b47a 42 }
WiredHome 0:9b0b4ae5b47a 43
WiredHome 0:9b0b4ae5b47a 44 Keypad::~Keypad() {
WiredHome 0:9b0b4ae5b47a 45 }
WiredHome 0:9b0b4ae5b47a 46
WiredHome 1:7feeebbd8367 47 bool Keypad::SetKeyboard(const keyboard_t * _kbd, char _enter_key, char _esc_key) {
WiredHome 1:7feeebbd8367 48 if (_kbd)
WiredHome 1:7feeebbd8367 49 kbd = _kbd;
WiredHome 1:7feeebbd8367 50 else
WiredHome 1:7feeebbd8367 51 kbd = &internalkbd;
WiredHome 1:7feeebbd8367 52 enter_key = _enter_key;
WiredHome 1:7feeebbd8367 53 esc_key = _esc_key;
WiredHome 1:7feeebbd8367 54 return true;
WiredHome 1:7feeebbd8367 55 }
WiredHome 1:7feeebbd8367 56
WiredHome 0:9b0b4ae5b47a 57 void Keypad::DrawKey(rect_t r, char c, bool invert) {
WiredHome 2:6d05764dfde7 58 ra.fillroundrect(r, 2, 2, invert ? fore : back);
WiredHome 2:6d05764dfde7 59 ra.roundrect(r, 2, 2, invert ? back : fore);
WiredHome 0:9b0b4ae5b47a 60 ra.SetTextCursor(r.p1.x+(r.p2.x-r.p1.x)/2-ra.fontwidth()/2, r.p1.y+2);
WiredHome 1:7feeebbd8367 61 if (invert) {
WiredHome 1:7feeebbd8367 62 ra.foreground(back);
WiredHome 1:7feeebbd8367 63 ra.background(fore);
WiredHome 3:402f1126a3ec 64 ra.SetTextCursorControl(RA8875::NOCURSOR);
WiredHome 1:7feeebbd8367 65 }
WiredHome 0:9b0b4ae5b47a 66 ra.putc(c);
WiredHome 1:7feeebbd8367 67 if (invert) {
WiredHome 1:7feeebbd8367 68 ra.foreground(fore);
WiredHome 1:7feeebbd8367 69 ra.background(back);
WiredHome 1:7feeebbd8367 70 }
WiredHome 0:9b0b4ae5b47a 71 }
WiredHome 0:9b0b4ae5b47a 72
WiredHome 0:9b0b4ae5b47a 73 void Keypad::Erase(color_t c) {
WiredHome 0:9b0b4ae5b47a 74 dim_t kH = ra.fontheight() + 4;
WiredHome 1:7feeebbd8367 75 rect_t r = ComputeKeypadRect();
WiredHome 1:7feeebbd8367 76
WiredHome 0:9b0b4ae5b47a 77 ra.fillrect(r, c);
WiredHome 0:9b0b4ae5b47a 78 }
WiredHome 0:9b0b4ae5b47a 79
WiredHome 0:9b0b4ae5b47a 80 void Keypad::DrawInputPanel(const char * prompt) {
WiredHome 0:9b0b4ae5b47a 81 dim_t kH = ra.fontheight() + 4;
WiredHome 1:7feeebbd8367 82 rect_t r = ComputeKeypadRect();
WiredHome 0:9b0b4ae5b47a 83
WiredHome 0:9b0b4ae5b47a 84 ra.fillrect(r, back);
WiredHome 0:9b0b4ae5b47a 85 ra.foreground(fore);
WiredHome 0:9b0b4ae5b47a 86 ra.background(back);
WiredHome 0:9b0b4ae5b47a 87 ra.SetTextCursor(r.p1.x,r.p1.y+2);
WiredHome 0:9b0b4ae5b47a 88 ra.puts(prompt);
WiredHome 0:9b0b4ae5b47a 89 userText = ra.GetTextCursor();
WiredHome 0:9b0b4ae5b47a 90 DrawKeypad();
WiredHome 0:9b0b4ae5b47a 91 }
WiredHome 0:9b0b4ae5b47a 92
WiredHome 1:7feeebbd8367 93 rect_t Keypad::ComputeKeypadRect(void) {
WiredHome 1:7feeebbd8367 94 dim_t kH = ra.fontheight() + 4;
WiredHome 1:7feeebbd8367 95 rect_t r;
WiredHome 1:7feeebbd8367 96
WiredHome 1:7feeebbd8367 97 if (kbd->x <= 0)
WiredHome 1:7feeebbd8367 98 r.p1.x = 0;
WiredHome 1:7feeebbd8367 99 else
WiredHome 1:7feeebbd8367 100 r.p1.x = kbd->x;
WiredHome 1:7feeebbd8367 101 if (kbd->y <= 0)
WiredHome 1:7feeebbd8367 102 r.p1.y = ra.height() - (kH * (kbd->rows+1)) - 1;
WiredHome 1:7feeebbd8367 103 else
WiredHome 1:7feeebbd8367 104 r.p1.y = kbd->y;
WiredHome 1:7feeebbd8367 105 if (kbd->width == 0)
WiredHome 1:7feeebbd8367 106 r.p2.x = ra.width() - 1;
WiredHome 1:7feeebbd8367 107 else
WiredHome 1:7feeebbd8367 108 r.p2.x = r.p1.x + kbd->width - 1;
WiredHome 1:7feeebbd8367 109 if (kbd->height == 0)
WiredHome 1:7feeebbd8367 110 r.p2.y = ra.height() - 1;
WiredHome 1:7feeebbd8367 111 else
WiredHome 1:7feeebbd8367 112 r.p2.y = r.p1.y + kbd->height - 1;
WiredHome 3:402f1126a3ec 113 //printf("KeypadRect (%d,%d) - (%d,%d)\r\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y);
WiredHome 1:7feeebbd8367 114 return r;
WiredHome 1:7feeebbd8367 115 }
WiredHome 1:7feeebbd8367 116
WiredHome 0:9b0b4ae5b47a 117 void Keypad::DrawKeypad(void) {
WiredHome 0:9b0b4ae5b47a 118 dim_t fW = ra.fontwidth();
WiredHome 0:9b0b4ae5b47a 119 dim_t fH = ra.fontheight();
WiredHome 1:7feeebbd8367 120 dim_t kW;
WiredHome 0:9b0b4ae5b47a 121 dim_t kH = fH + 4;
WiredHome 1:7feeebbd8367 122
WiredHome 1:7feeebbd8367 123 const char * p = kbd->keydef1;
WiredHome 1:7feeebbd8367 124 rect_t r = ComputeKeypadRect();
WiredHome 1:7feeebbd8367 125 rect_t ref = r;
WiredHome 1:7feeebbd8367 126 kW = (ref.p2.x - ref.p1.x) / (kbd->cols+1);
WiredHome 3:402f1126a3ec 127 //printf("DrawKeypad kW=%d from (%d,%d) %d\r\n", kW, ref.p2.x, ref.p1.x, kbd->cols+1);
WiredHome 1:7feeebbd8367 128 r.p1.y += kH;
WiredHome 0:9b0b4ae5b47a 129 if (shift)
WiredHome 1:7feeebbd8367 130 p = kbd->keydef2;
WiredHome 0:9b0b4ae5b47a 131 while (*p || *(p+2)) {
WiredHome 0:9b0b4ae5b47a 132 if (*p == 0) {
WiredHome 1:7feeebbd8367 133 r.p1.x = ref.p1.x;
WiredHome 0:9b0b4ae5b47a 134 r.p1.y += kH;
WiredHome 0:9b0b4ae5b47a 135 } else {
WiredHome 0:9b0b4ae5b47a 136 const char * symbol = p + 1;
WiredHome 0:9b0b4ae5b47a 137 if (*symbol >= 0x10) {
WiredHome 0:9b0b4ae5b47a 138 r.p2.x = r.p1.x + (kW * *p)/10;
WiredHome 0:9b0b4ae5b47a 139 r.p2.y = r.p1.y + kH;
WiredHome 0:9b0b4ae5b47a 140 DrawKey(r,*symbol);
WiredHome 0:9b0b4ae5b47a 141 }
WiredHome 0:9b0b4ae5b47a 142 r.p1.x += (kW * *p)/10;
WiredHome 0:9b0b4ae5b47a 143 }
WiredHome 0:9b0b4ae5b47a 144 p+=2;
WiredHome 0:9b0b4ae5b47a 145 }
WiredHome 0:9b0b4ae5b47a 146 }
WiredHome 0:9b0b4ae5b47a 147
WiredHome 0:9b0b4ae5b47a 148 char Keypad::isKeyTouched(point_t * point, rect_t * rectTouched) {
WiredHome 1:7feeebbd8367 149 dim_t kW;
WiredHome 0:9b0b4ae5b47a 150 dim_t kH = ra.fontheight() + 4;
WiredHome 0:9b0b4ae5b47a 151
WiredHome 1:7feeebbd8367 152 const char * p = kbd->keydef1;
WiredHome 1:7feeebbd8367 153 rect_t r = ComputeKeypadRect();
WiredHome 1:7feeebbd8367 154 rect_t ref = r;
WiredHome 1:7feeebbd8367 155 kW = (ref.p2.x - ref.p1.x) / (kbd->cols+1);
WiredHome 1:7feeebbd8367 156 r.p1.y = r.p1.y + kH;
WiredHome 0:9b0b4ae5b47a 157 if (shift)
WiredHome 1:7feeebbd8367 158 p = kbd->keydef2;
WiredHome 0:9b0b4ae5b47a 159 while (*p || *(p+2)) {
WiredHome 0:9b0b4ae5b47a 160 if (*p == 0) {
WiredHome 1:7feeebbd8367 161 r.p1.x = ref.p1.x;
WiredHome 0:9b0b4ae5b47a 162 r.p1.y += kH;
WiredHome 0:9b0b4ae5b47a 163 } else {
WiredHome 0:9b0b4ae5b47a 164 const char * symbol = p + 1;
WiredHome 0:9b0b4ae5b47a 165 if (*symbol >= 0x10) {
WiredHome 0:9b0b4ae5b47a 166 r.p2.x = r.p1.x + (kW * *p)/10;
WiredHome 0:9b0b4ae5b47a 167 r.p2.y = r.p1.y + kH;
WiredHome 0:9b0b4ae5b47a 168 if (ra.Intersect(r, *point)) {
WiredHome 0:9b0b4ae5b47a 169 if (rectTouched)
WiredHome 0:9b0b4ae5b47a 170 *rectTouched = r;
WiredHome 0:9b0b4ae5b47a 171 return (*symbol);
WiredHome 0:9b0b4ae5b47a 172 }
WiredHome 0:9b0b4ae5b47a 173 }
WiredHome 0:9b0b4ae5b47a 174 r.p1.x += (kW * *p)/10;
WiredHome 0:9b0b4ae5b47a 175 }
WiredHome 0:9b0b4ae5b47a 176 p+=2;
WiredHome 0:9b0b4ae5b47a 177 }
WiredHome 0:9b0b4ae5b47a 178 return 0;
WiredHome 0:9b0b4ae5b47a 179 }
WiredHome 0:9b0b4ae5b47a 180
WiredHome 0:9b0b4ae5b47a 181 void Keypad::ShowBufferMetrics(void) {
WiredHome 1:7feeebbd8367 182 rect_t r = ComputeKeypadRect();
WiredHome 3:402f1126a3ec 183 ra.SetTextCursor(r.p2.x-1-ra.fontwidth()*5, r.p1.y+2);
WiredHome 3:402f1126a3ec 184 ra.printf("%02d/%02d", pNext - pStart, bufSize); // "001/100"
WiredHome 1:7feeebbd8367 185 //ra.SetTextCursor(ra.width()-1-ra.fontwidth()*7, ra.height()-1-ra.fontheight());
WiredHome 0:9b0b4ae5b47a 186 ra.SetTextCursor(userText.x, userText.y);
WiredHome 0:9b0b4ae5b47a 187 ra.SetTextCursorControl(RA8875::UNDER);
WiredHome 0:9b0b4ae5b47a 188 }
WiredHome 0:9b0b4ae5b47a 189
WiredHome 0:9b0b4ae5b47a 190 bool Keypad::GetString(char * buffer, size_t size, const char * prompt, char mask) {
WiredHome 0:9b0b4ae5b47a 191 point_t point = {0, 0};
WiredHome 0:9b0b4ae5b47a 192
WiredHome 0:9b0b4ae5b47a 193 pStart = pNext = buffer;
WiredHome 0:9b0b4ae5b47a 194 bufSize = size;
WiredHome 0:9b0b4ae5b47a 195 DrawInputPanel(prompt);
WiredHome 0:9b0b4ae5b47a 196 ShowBufferMetrics();
WiredHome 0:9b0b4ae5b47a 197 while (1) {
WiredHome 0:9b0b4ae5b47a 198 if (touch == ra.TouchPanelReadable(&point)) {
WiredHome 0:9b0b4ae5b47a 199 rect_t touchRect;
WiredHome 1:7feeebbd8367 200 // find out if they touched a key;
WiredHome 0:9b0b4ae5b47a 201 char key = isKeyTouched(&point, &touchRect);
WiredHome 0:9b0b4ae5b47a 202 if (key) {
WiredHome 0:9b0b4ae5b47a 203 DrawKey(touchRect, key, true);
WiredHome 0:9b0b4ae5b47a 204 wait_ms(50);
WiredHome 0:9b0b4ae5b47a 205 TouchCode_t is;
WiredHome 0:9b0b4ae5b47a 206 do {
WiredHome 0:9b0b4ae5b47a 207 is = ra.TouchPanelReadable(NULL);
WiredHome 1:7feeebbd8367 208 //printf("is: %d\r\n", is);
WiredHome 0:9b0b4ae5b47a 209 } while (is != no_touch);
WiredHome 0:9b0b4ae5b47a 210 DrawKey(touchRect, key);
WiredHome 0:9b0b4ae5b47a 211 }
WiredHome 3:402f1126a3ec 212 //printf("Touch %02X at (%d,%d)\r\n", key, point.x, point.y);
WiredHome 1:7feeebbd8367 213 if (key == enter_key) {
WiredHome 0:9b0b4ae5b47a 214 *pNext = '\0';
WiredHome 0:9b0b4ae5b47a 215 ra.SetTextCursorControl();
WiredHome 0:9b0b4ae5b47a 216 return true;
WiredHome 1:7feeebbd8367 217 } else if (key == esc_key) {
WiredHome 0:9b0b4ae5b47a 218 *buffer = '\0';
WiredHome 0:9b0b4ae5b47a 219 ra.SetTextCursorControl();
WiredHome 0:9b0b4ae5b47a 220 return false;
WiredHome 1:7feeebbd8367 221 } else if (key == KYBD_SYM_BS) {
WiredHome 0:9b0b4ae5b47a 222 if (pNext > buffer) {
WiredHome 0:9b0b4ae5b47a 223 pNext--;
WiredHome 0:9b0b4ae5b47a 224 // blank the last char
WiredHome 0:9b0b4ae5b47a 225 userText.x -= ra.fontwidth();
WiredHome 0:9b0b4ae5b47a 226 ra.SetTextCursor(userText.x, userText.y);
WiredHome 0:9b0b4ae5b47a 227 ra.putc(' ');
WiredHome 0:9b0b4ae5b47a 228 }
WiredHome 1:7feeebbd8367 229 } else if (key == KYBD_SYM_TAB) {
WiredHome 0:9b0b4ae5b47a 230 *pNext++ = ' ';
WiredHome 0:9b0b4ae5b47a 231 ra.SetTextCursor(userText.x, userText.y);
WiredHome 0:9b0b4ae5b47a 232 ra.putc(' ');
WiredHome 0:9b0b4ae5b47a 233 userText.x += ra.fontwidth();
WiredHome 1:7feeebbd8367 234 } else if (key == KYBD_SYM_SHIFT) {
WiredHome 0:9b0b4ae5b47a 235 shift = !shift;
WiredHome 0:9b0b4ae5b47a 236 DrawKeypad();
WiredHome 0:9b0b4ae5b47a 237 } else if (key) {
WiredHome 0:9b0b4ae5b47a 238 *pNext++ = key;
WiredHome 0:9b0b4ae5b47a 239 ra.SetTextCursor(userText.x, userText.y);
WiredHome 0:9b0b4ae5b47a 240 if (mask)
WiredHome 0:9b0b4ae5b47a 241 ra.putc(mask);
WiredHome 0:9b0b4ae5b47a 242 else
WiredHome 0:9b0b4ae5b47a 243 ra.putc(key);
WiredHome 0:9b0b4ae5b47a 244 userText.x += ra.fontwidth();
WiredHome 0:9b0b4ae5b47a 245 }
WiredHome 0:9b0b4ae5b47a 246 if ((pNext - buffer) >= (size - 1)) {
WiredHome 0:9b0b4ae5b47a 247 *pNext = '\0';
WiredHome 0:9b0b4ae5b47a 248 ra.SetTextCursorControl();
WiredHome 0:9b0b4ae5b47a 249 return true;
WiredHome 0:9b0b4ae5b47a 250 }
WiredHome 0:9b0b4ae5b47a 251 ShowBufferMetrics();
WiredHome 0:9b0b4ae5b47a 252 }
WiredHome 0:9b0b4ae5b47a 253 }
WiredHome 0:9b0b4ae5b47a 254 }