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

Dependents:   RA8875_KeyPadDemo PUB_RA8875_Keypad IAC_Final_Monil_copy

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();
+        }
+    }
+}