Library for virtual onscreen keyboard for STM32F746 Disco board
Dependencies: BSP_DISCO_F746NG mbed
Diff: user/keyboard.c
- 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; +}