Updated software keyboard to center, and provice press indicators

This commit is contained in:
kkoenig1@optonline.com
2021-08-25 12:28:22 -04:00
parent b6c126f4e4
commit 1c1d542839
3 changed files with 166 additions and 29 deletions
+144 -29
View File
@@ -79,7 +79,8 @@ const char * const KEYBOARD_NUMBERS[] = {
KEYBOARD_SET_LETTERS KEYBOARD_SPACE KEYBOARD_ENTER
};
const char * const * const KEYBOARD_LAYOUTS[] = {
#define NUMBER_OF_KEYBOARD_LAYOUTS 4
const char * const * const KEYBOARD_LAYOUTS[NUMBER_OF_KEYBOARD_LAYOUTS] = {
KEYBOARD_UPPERCASE,
KEYBOARD_LOWERCASE,
KEYBOARD_LOWERCASE,
@@ -97,70 +98,169 @@ TextKeyboard::~TextKeyboard()
_instance = nullptr;
}
int TextKeyboard::getCharWidth(const char c)
{
if (int8_t(c) < 0) return KEYBOARD_BITMAP_WIDTH;
switch (c)
{
case ' ': return 15;
case KEYBOARD_SPACE[0]: return KEYBOARD_SPACE_WIDTH;
case KEYBOARD_ENTER[0]: return KEYBOARD_ENTER_WIDTH;
default: return KEYBOARD_CHAR_WIDTH;
}
}
int TextKeyboard::calculateMaxWidth()
{
int maxWidth = 0;
for (uint8_t i = 0; i < NUMBER_OF_KEYBOARD_LAYOUTS; i++) {
int lineWidth = 0;
const char * c = layout[i];
while (*c) {
lineWidth += getCharWidth(*c);
maxWidth = max(lineWidth, maxWidth);
c++;
}
}
return maxWidth;
}
void TextKeyboard::paint(BitmapBuffer * dc)
{
lcdSetColor(RGB(0xE0, 0xE0, 0xE0));
dc->clear(CUSTOM_COLOR);
for (uint8_t i=0; i<4; i++) {
coord_t y = 15 + i * 40;
coord_t x = 15;
// center the keyboard
coord_t start_x = (dc->width() - calculateMaxWidth()) / 2;
for (uint8_t i = 0; i < NUMBER_OF_KEYBOARD_LAYOUTS; i++) {
coord_t y = KEYBOARD_OFFSET_Y + i * KEYBOARD_ROW_HEIGHT;
coord_t x = start_x;
const char * c = layout[i];
while (*c) {
if (*c == ' ') {
x += 15;
}
else if (*c == KEYBOARD_SPACE[0]) {
if (*c == KEYBOARD_SPACE[0]) {
// spacebar
dc->drawBitmapPattern(x, y, LBM_KEY_SPACEBAR, COLOR_THEME_SECONDARY1);
x += 135;
}
else if (*c == KEYBOARD_ENTER[0]) {
// enter
dc->drawSolidFilledRect(x, y-2, 80, 25, COLOR_THEME_DISABLED);
dc->drawText(x+40, y, "ENTER", CENTERED);
x += 80;
dc->drawSolidFilledRect(x, y - 2, KEYBOARD_ENTER_WIDTH, 25, COLOR_THEME_DISABLED);
dc->drawText(x + KEYBOARD_ENTER_WIDTH / 2, y + 2, "ENTER", CENTERED);
}
else if (int8_t(*c) < 0) {
dc->drawBitmapPattern(x, y, LBM_SPECIAL_KEYS[uint8_t(*c - 128)], COLOR_THEME_SECONDARY1);
x += 45;
const uint8_t *pBitmap = LBM_SPECIAL_KEYS[uint8_t(*c - 128)];
uint8_t bitmapWidth = *pBitmap, bitmapHeight = *(pBitmap + 2);
if (touched && *c == touch_key) {
dc->drawSolidFilledRect(x - 2, y + 3, bitmapWidth + 4, bitmapHeight + 4, COLOR_THEME_SECONDARY2);
}
dc->drawBitmapPattern(x, y + 5, pBitmap, COLOR_THEME_SECONDARY1);
}
else {
dc->drawSizedText(x, y, c, 1);
x += 30;
if (touched && *c == touch_key) {
dc->drawSolidFilledRect(x - KEYBOARD_CHAR_WIDTH / 2, y - ((KEYBOARD_ROW_HEIGHT - 16) / 2), KEYBOARD_CHAR_WIDTH, KEYBOARD_ROW_HEIGHT, COLOR_THEME_FOCUS);
}
dc->drawSizedText(x, y, c, 1, CENTERED);
}
x += getCharWidth(*c);
c++;
}
}
}
bool TextKeyboard::onTouchStart(coord_t x, coord_t y)
{
// remove the centering. If x < 0 then this is an invalid touch event
x -= (this->width() - calculateMaxWidth()) / 2;
if (x < 0) {
if (touched) {
touched = false;
invalidate();
}
return true;
}
touched = false;
uint8_t row = max<coord_t>(0, y - 5) / KEYBOARD_ROW_HEIGHT;
const char * key = layout[row];
while(*key) {
if (*key == KEYBOARD_SPACE[0] && x <= KEYBOARD_SPACE_WIDTH) {
touch_key = KEYBOARD_SPACE[0];
touched = true;
break;
}
else if (*key == KEYBOARD_ENTER[0] && x <= KEYBOARD_ENTER_WIDTH) {
touch_key = KEYBOARD_ENTER[0];
touched = true;
break;
}
else if (int8_t(*key) < 0 && x <= KEYBOARD_BITMAP_WIDTH) {
if (uint8_t(*key) == 128) {
touch_key = KEYBOARD_BACKSPACE[0];
touched = true;
break;
} else {
touched = false;
break;
}
}
else if (*key != ' ' && (x >= -(KEYBOARD_CHAR_WIDTH / 2) && x <= KEYBOARD_CHAR_WIDTH / 2)) {
touch_key = *key;
touched = true;
break;
}
x -= getCharWidth(*key);
key++;
if (touched) {
invalidate();
break;
}
}
return true;
}
bool TextKeyboard::onTouchEnd(coord_t x, coord_t y)
{
// remove the centering width, if x < 0 then this is an invalid touch on a centered keyboard.
x -= (this->width() - calculateMaxWidth()) / 2;
if (x < 0) {
touched = false;
return true;
}
onKeyPress();
uint8_t row = max<coord_t>(0, y - 5) / 40;
if (touched)
invalidate();
touched = false;
uint8_t row = max<coord_t>(0, y - 5) / KEYBOARD_ROW_HEIGHT;
const char * key = layout[row];
while (*key) {
if (*key == ' ') {
x -= 15;
}
else if (*key == KEYBOARD_SPACE[0]) {
if (x <= 135) {
if (*key == KEYBOARD_SPACE[0]) {
if (x <= KEYBOARD_SPACE_WIDTH) {
pushEvent(EVT_VIRTUAL_KEY(' '));
return true;
}
x -= 135;
}
else if (*key == KEYBOARD_ENTER[0]) {
if (x <= 80) {
if (x <= KEYBOARD_ENTER_WIDTH) {
// enter
hide();
return true;
}
x -= 80;
}
else if (int8_t(*key) < 0) {
if (x <= 45) {
if (x <= KEYBOARD_BITMAP_WIDTH) {
uint8_t specialKey = *key;
if (specialKey == 128) {
// backspace
@@ -172,17 +272,32 @@ bool TextKeyboard::onTouchEnd(coord_t x, coord_t y)
}
break;
}
x -= 45;
}
else {
if (x <= 30) {
if (x <= KEYBOARD_CHAR_WIDTH && *key != ' ') {
pushEvent(EVT_VIRTUAL_KEY(*key));
return true;
}
x -= 30;
}
x -= getCharWidth(*key);
key++;
}
return true;
}
bool TextKeyboard::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY)
{
if (touched)
invalidate();
touched = false;
return false;
}
#if defined(HARDWARE_KEYS)
void TextKeyboard::onEvent(event_t event)
{
}
#endif
+19
View File
@@ -29,6 +29,13 @@
#define KEYBOARD_SET_LETTERS "\203"
#define KEYBOARD_SET_NUMBERS "\204"
#define KEYBOARD_OFFSET_Y 15
#define KEYBOARD_ROW_HEIGHT 40
#define KEYBOARD_CHAR_WIDTH 30
#define KEYBOARD_SPACE_WIDTH 135
#define KEYBOARD_ENTER_WIDTH 80
#define KEYBOARD_BITMAP_WIDTH 45
class TextKeyboard : public Keyboard {
public:
TextKeyboard();
@@ -53,10 +60,22 @@ class TextKeyboard : public Keyboard {
#if defined(HARDWARE_TOUCH)
bool onTouchEnd(coord_t x, coord_t y) override;
bool onTouchStart(coord_t x, coord_t y) override;
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override;
#endif
protected:
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
static TextKeyboard * _instance;
const char * const * layout;
private:
int calculateMaxWidth();
int getCharWidth(const char c);
char touch_key = -128;
bool touched = false;
};
+3
View File
@@ -170,6 +170,9 @@ void TextEdit::onEvent(event_t event)
case EVT_KEY_BREAK(KEY_EXIT):
changeEnd();
#if defined(SOFTWARE_KEYBOARD)
Keyboard::hide();
#endif
FormField::onEvent(event);
break;