Library for virtual onscreen keyboard for STM32F746 Disco board

Dependencies:   BSP_DISCO_F746NG mbed

Revision:
0:3ea368f65bca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/user/keyboard.c	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,480 @@
+/*
+ *******************************************************************************
+ * Библиотека Keyboard виртуальной клавиатуры для дисплея с тач-экраном на демо-
+ * плате STM32F746NG Discovery
+ *
+ * Файл "keyboard.c"
+ *******************************************************************************
+ */  
+
+/* Добавляем заголовочный файл */
+#include "keyboard.h"
+
+/* Структуры клаватуры и тач-экрана */
+Keyboard_TypeDef keyboard;
+TS_StateTypeDef tScreen;
+
+/* Функции для работы с экранной клавиатурой */
+
+/* Инициализация и вывод клавиатуры на дисплей */
+uint8_t Keyboard_init(uint16_t  x_value, uint16_t   y_value)
+{
+    uint8_t i;
+    
+    /* Координаты верхнего левого угла клавиатуры на экране, служат точкой
+     * отсчета для определения расположения всех остальных элементов
+     */
+    keyboard.posX = x_value;
+    keyboard.posY = y_value;
+    
+    /* По умолчанию на клавиатуре английская раскладка в верхнем регистре */
+    keyboard.mode = MODE_UPPER_CASE;
+    
+    /* Блок инициализации для стандартных клавиш */
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для верхнего ряда */
+    for (i = 0; i < 10; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 3 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * i;
+        keyboard.key[i].posY = keyboard.posY + 3;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED; 
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из верхнего ряда для различных 
+     * раскладок клавиатуры 
+     */
+    keyboard.key[0].value[0] = 'Q';
+    keyboard.key[0].value[1] = 'q';
+    keyboard.key[0].value[2] = '1';
+    
+    keyboard.key[1].value[0] = 'W';
+    keyboard.key[1].value[1] = 'w';
+    keyboard.key[1].value[2] = '2';
+    
+    keyboard.key[2].value[0] = 'E';
+    keyboard.key[2].value[1] = 'e';
+    keyboard.key[2].value[2] = '3';
+    
+    keyboard.key[3].value[0] = 'R';
+    keyboard.key[3].value[1] = 'r';
+    keyboard.key[3].value[2] = '4';
+    
+    keyboard.key[4].value[0] = 'T';
+    keyboard.key[4].value[1] = 't';
+    keyboard.key[4].value[2] = '5';
+    
+    keyboard.key[5].value[0] = 'Y';
+    keyboard.key[5].value[1] = 'y';
+    keyboard.key[5].value[2] = '6';
+    
+    keyboard.key[6].value[0] = 'U';
+    keyboard.key[6].value[1] = 'u';
+    keyboard.key[6].value[2] = '7';
+    
+    keyboard.key[7].value[0] = 'I';
+    keyboard.key[7].value[1] = 'i';
+    keyboard.key[7].value[2] = '8';
+    
+    keyboard.key[8].value[0] = 'O';
+    keyboard.key[8].value[1] = 'o';
+    keyboard.key[8].value[2] = '9';
+    
+    keyboard.key[9].value[0] = 'P';
+    keyboard.key[9].value[1] = 'p';
+    keyboard.key[9].value[2] = '0';
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для среднего ряда */  
+    for (i = 10; i < 19; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 27 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * (i - 10);
+        keyboard.key[i].posY = keyboard.posY + 3 + KEY_SMALL_HEIGHT + KEY_DISTANCE;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED; 
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из среднего ряда для различных
+     * раскладок клавиатуры
+     */
+    keyboard.key[10].value[0] = 'A';
+    keyboard.key[10].value[1] = 'a';
+    keyboard.key[10].value[2] = '1';
+    
+    keyboard.key[11].value[0] = 'S';
+    keyboard.key[11].value[1] = 's';
+    keyboard.key[11].value[2] = '2';
+    
+    keyboard.key[12].value[0] = 'D';
+    keyboard.key[12].value[1] = 'd';
+    keyboard.key[12].value[2] = '3';
+    
+    keyboard.key[13].value[0] = 'F';
+    keyboard.key[13].value[1] = 'f';
+    keyboard.key[13].value[2] = '4';
+    
+    keyboard.key[14].value[0] = 'G';
+    keyboard.key[14].value[1] = 'g';
+    keyboard.key[14].value[2] = '5';
+    
+    keyboard.key[15].value[0] = 'H';
+    keyboard.key[15].value[1] = 'h';
+    keyboard.key[15].value[2] = '6';
+    
+    keyboard.key[16].value[0] = 'J';
+    keyboard.key[16].value[1] = 'j';
+    keyboard.key[16].value[2] = '7';
+    
+    keyboard.key[17].value[0] = 'K';
+    keyboard.key[17].value[1] = 'k';
+    keyboard.key[17].value[2] = '8';
+    
+    keyboard.key[18].value[0] = 'L';
+    keyboard.key[18].value[1] = 'l';
+    keyboard.key[18].value[2] = '9';
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для нижнего ряда */    
+    for (i = 19; i < 26; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 51 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * (i - 19);
+        keyboard.key[i].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 2;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED;
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из нижнего ряда для различных
+     * раскладок лавиатуры
+     */
+    keyboard.key[19].value[0] = 'Z';
+    keyboard.key[19].value[1] = 'z';
+    keyboard.key[19].value[2] = '1';
+    
+    keyboard.key[20].value[0] = 'X';
+    keyboard.key[20].value[1] = 'x';
+    keyboard.key[20].value[2] = '2';
+    
+    keyboard.key[21].value[0] = 'C';
+    keyboard.key[21].value[1] = 'c';
+    keyboard.key[21].value[2] = '3';
+    
+    keyboard.key[22].value[0] = 'V';
+    keyboard.key[22].value[1] = 'v';
+    keyboard.key[22].value[2] = '4';
+    
+    keyboard.key[23].value[0] = 'B';
+    keyboard.key[23].value[1] = 'b';
+    keyboard.key[23].value[2] = '5';
+    
+    keyboard.key[24].value[0] = 'N';
+    keyboard.key[24].value[1] = 'n';
+    keyboard.key[24].value[2] = '6';
+    
+    keyboard.key[25].value[0] = 'M';
+    keyboard.key[25].value[1] = 'm';
+    keyboard.key[25].value[2] = '7';
+    
+    /* Блок инициализации для специальных клавиш */
+    
+    /* Клавиша "Enter" */
+    keyboard.key[26].id = 26;
+    keyboard.key[26].posX = 51 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * 7;
+    keyboard.key[26].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 2;
+    keyboard.key[26].dimX = KEY_ENTER_LENGTH;
+    keyboard.key[26].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[26].status = KEY_RELEASED;
+    keyboard.key[26].value[0] = KEY_ENTER_VALUE;
+    keyboard.key[26].value[1] = KEY_ENTER_VALUE;
+    keyboard.key[26].value[2] = KEY_ENTER_VALUE;
+    
+    /* Клавиша "Shift" */
+    keyboard.key[27].id = 27;
+    keyboard.key[27].posX = 3;
+    keyboard.key[27].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[27].dimX = KEY_SHIFT_LENGTH;
+    keyboard.key[27].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[27].status = KEY_RELEASED;
+    keyboard.key[27].value[0] = KEY_SHIFT_VALUE;
+    keyboard.key[27].value[1] = KEY_SHIFT_VALUE;
+    keyboard.key[27].value[2] = KEY_SHIFT_VALUE;
+    
+    /* Клавиша "Space" */
+    keyboard.key[28].id = 28;
+    keyboard.key[28].posX = 27 + (KEY_SMALL_LENGTH + KEY_DISTANCE) * 3;
+    keyboard.key[28].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[28].dimX = KEY_SPACE_LENGTH;
+    keyboard.key[28].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[28].status = KEY_RELEASED;
+    keyboard.key[28].value[0] = KEY_SPACE_VALUE;
+    keyboard.key[28].value[1] = KEY_SPACE_VALUE;
+    keyboard.key[28].value[2] = KEY_SPACE_VALUE;
+    
+    /* Клавиша "Backspace" */
+    keyboard.key[29].id = 29;
+    keyboard.key[29].posX = keyboard.posX + 27 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * 8;
+    keyboard.key[29].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[29].dimX = KEY_BACKSPACE_LENGTH;
+    keyboard.key[29].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[29].status = KEY_RELEASED;
+    keyboard.key[29].value[0] = KEY_BACKSPACE_VALUE;
+    keyboard.key[29].value[1] = KEY_BACKSPACE_VALUE;
+    keyboard.key[29].value[2] = KEY_BACKSPACE_VALUE;
+    
+    /* Отрисовываем клавиатуру на экране*/
+    Keyboard_display_all();
+    
+    return 0;
+}
+
+/* Отрисовка клавиатуры на экране */
+uint8_t Keyboard_display_all(void)
+{
+    uint8_t i;
+    
+    /* Получаем значение цвета фона экрана*/
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    
+    /* Закрашиваем весь экран цветом фона*/
+    BSP_LCD_Clear(back_color);
+
+    /* Отрисовываем каждую клавишу на клавиатуре */
+    for (i = 0; i < KEY_NUMBER; i++)
+    {
+        Key_display_normal(i);
+    }
+    
+    return 0;
+}
+
+/* Отрисовка отдельной клавишы клавиатуры на экране */
+uint8_t Key_display_normal(uint8_t id)
+{
+    /* Получаем значение цвета фона экрана и цвета шрифта */
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    uint32_t text_color = BSP_LCD_GetTextColor();
+    
+    /* Меняем цвета и закрашиваем место для клавишы на экране цветом фона */
+    BSP_LCD_SetTextColor(back_color);
+    BSP_LCD_SetBackColor(text_color);               
+    BSP_LCD_FillRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    
+    /* Возвращаем прежние значения цвета фона экрана и цвета шрифта*/
+    BSP_LCD_SetTextColor(text_color);
+    BSP_LCD_SetBackColor(back_color);
+    
+    /* Рисуем рамку рамку вокруг клавишы и замыкающий пиксель в нижнем правом углу */
+    BSP_LCD_DrawRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    BSP_LCD_DrawPixel(keyboard.key[id].posX + keyboard.key[id].dimX, keyboard.key[id].posY + keyboard.key[id].dimY, text_color);
+    
+    /* Выводим значение клавишы в текущей раскладке клавиатуры */
+    BSP_LCD_DisplayChar(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, keyboard.key[id].value[keyboard.mode]);
+    
+    /* Для специальных клавиш выводим больше одного символа */
+    Key_display_specials(id);
+    
+    return 0;
+}
+
+/* Отрисовка отдельной клавишы клавиатуры на экране (в инвертированном цвете) */
+uint8_t Key_display_inverted(uint8_t id)
+{
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    uint32_t text_color = BSP_LCD_GetTextColor();
+    
+    /* Закрашиваем место для клавишы на экране цветом шрифта */
+    BSP_LCD_FillRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    
+    /* Меняем цвета и выводим значение клавишы в текущей раскладке клавиатуры */
+    BSP_LCD_SetTextColor(back_color);
+    BSP_LCD_SetBackColor(text_color);
+    BSP_LCD_DisplayChar(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, keyboard.key[id].value[keyboard.mode]);
+    
+    /* Для спецмальных клавиш выводим больше одного символа */
+    Key_display_specials(id);
+    
+    /* Возвращаем прежние значения цвета фона экрана и цвета шрифта */
+    BSP_LCD_SetTextColor(text_color);
+    BSP_LCD_SetBackColor(back_color);
+    
+    return 0;
+}
+
+/* Вывод значения специальных клавиш клавиатуры */ 
+uint8_t Key_display_specials(uint8_t id)
+{
+    /* Клавиша "Enter" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_ENTER_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, (uint8_t *) "Enter", LEFT_MODE);
+    }
+    /* Клавиша "Shift" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_SHIFT_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 4, keyboard.key[id].posY + 8, (uint8_t *) "Shft", LEFT_MODE);
+    }
+    
+    /* Клаиша "Space" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_SPACE_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 32, keyboard.key[id].posY + 8, (uint8_t *) "Space", LEFT_MODE);
+    }
+    
+    /* Клавиша "Backspace" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_BACKSPACE_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 4, keyboard.key[id].posY + 8, (uint8_t *) "Bspc", LEFT_MODE);
+    }
+    
+    return 0;
+}
+
+/* Проверка ввода на экранной клавиатуре */
+uint8_t Keyboard_check(void)
+{
+    uint8_t i;
+    uint8_t j;
+    
+    /* Проверяем состояния драйвера тач-экрана */
+    BSP_TS_GetState(&tScreen);
+    
+    /* Если произошло касание */
+    if (tScreen.touchDetected)
+    {
+        for (i = 0; i < KEY_NUMBER; i++)
+        {
+            /* Если координаты касания лежат в границах какой-либо из ненажатых кнопок +/- 4 пикселя */
+            if (((tScreen.touchX[0] >= keyboard.key[i].posX - 4) && (tScreen.touchX[0] < keyboard.key[i].posX + keyboard.key[i].dimX + 4)) &&
+                    ((tScreen.touchY[0] >= keyboard.key[i].posY - 4) && (tScreen.touchY[0] < keyboard.key[i].posY + keyboard.key[i].dimY + 4)) && 
+                    (keyboard.key[i].status == KEY_RELEASED))
+            {
+                /* Отрисовываем нужную клавишу в инвертированном цвете*/
+                Key_display_inverted(i);
+                
+                /* Если до этого нажатие было зафиксировано на другой клавише,
+                 * отжимаем её и перерисовываем
+                 */
+                for (j = 0; j < KEY_NUMBER; j++)
+                {
+                    if (keyboard.key[j].status == KEY_PRESSED)
+                    {
+                        Key_display_normal(j);
+                        
+                        keyboard.key[j].status = KEY_RELEASED;
+                    }
+                }
+                
+                /* Меняем состояние клавишы, для которой было зафиксировано нажатие */
+                keyboard.key[i].status = KEY_PRESSED;
+                
+                /* Сбрасываем состояние драйвера тач-экрана */
+                BSP_TS_ResetTouchData(&tScreen);
+            }
+        }
+    }
+    /* Если касания нет, проверяем состояние каждой клавишы, возможно, касание 
+     * было до этого момента и следует обработать ввод
+     */
+    else
+    {
+        for (i = 0; i < KEY_NUMBER; i++)
+        {
+            /* Если клавиша в нажатом состоянии, отжимаем её и перерисовываем */
+            if (keyboard.key[i].status == KEY_PRESSED)
+            {
+                Key_display_normal(i);
+                
+                keyboard.key[i].status = KEY_RELEASED;
+                BSP_TS_ResetTouchData(&tScreen);
+                
+                /* Возвращаем пользовательский ввод */
+                return keyboard.key[i].value[keyboard.mode];
+            }
+        }
+    }
+    
+    return 0;
+}
+
+/* Обработчик ввода на экранной клавиатуре */
+uint8_t Keyboard_handler(char buffer[])
+{
+    uint8_t i;
+    uint8_t len;
+    uint8_t key;
+    
+    /* Проверяем, есть ли новое нажатие */
+    key = Keyboard_check();
+    
+    /* Если нажата стандартная клавиша или клавиша "Space" */
+    if ((key >= KEY_SPACE_VALUE) && (key != KEY_DELETE_VALUE))
+    {
+        /* Проверяем буффер клавиатуры и, если есть свободное место, добавляем
+         * символ с нажатой клавишы в буфер клавиатуры
+         */
+        i = strlen(keyboard.buffer);
+        if (i < KEY_BUFFER_LEN)
+        {
+            keyboard.buffer[i] = key;
+            keyboard.buffer[i + 1] = '\0';
+            
+            /* Отображаем буфер клавиатуры на верхней строчке дисплея */
+            BSP_LCD_ClearStringLine(0);
+            BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+        }
+    }
+    /* Если нажата специальная клавиша */
+    else
+    {
+        /* Если нажата клавиша "Enter", то копируем данные из буфера клавиатуры
+         * в пользовательский буфер и затираем данные в буфере клавиатуры
+         */
+        if (key == KEY_ENTER_VALUE)
+        {
+            len = strlen(keyboard.buffer);
+            
+            for (i = 0; i <= len; i++)
+            {
+                buffer[i] = keyboard.buffer[i];
+            }
+            
+            keyboard.buffer[0] = '\0';
+            
+            /* Затираем верхнюю строчку на дисплее */
+            BSP_LCD_ClearStringLine(0);
+            BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+        }
+        
+        /* Если нажата клавиша "Shift", меняем раскладку клавиатуры */
+        if (key == KEY_SHIFT_VALUE)
+        {
+            keyboard.mode = !keyboard.mode;
+            
+            for (i = 0; i < KEY_NUMBER; i++)
+            {
+                /* Выводим значение клавишы в новой раскладке */
+                BSP_LCD_DisplayChar(keyboard.key[i].posX + 8, keyboard.key[i].posY + 8, keyboard.key[i].value[keyboard.mode]);
+                Key_display_specials(i);
+            }
+        }
+        
+        /* Если нажата клавиша "Backspace", удаляем крайний символ из буфера 
+         * клавиатуры */ 
+        if (key == KEY_BACKSPACE_VALUE)
+        {
+            len = strlen(keyboard.buffer);
+            if (len != 0)
+            {
+                keyboard.buffer[len - 1] = '\0'; 
+                BSP_LCD_ClearStringLine(0);
+                BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+            }
+        }
+    }
+    
+    /* Возвращаем значение последней нажатой клавишы */
+    return key;
+}