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

Dependents:   RA8875_KeyPadDemo PUB_RA8875_Keypad IAC_Final_Monil_copy

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) {