feat(color): Shortcut keys for onscreen keyboards (#4355)

This commit is contained in:
philmoz
2023-11-27 21:52:08 +10:00
committed by GitHub
parent cf6169bdef
commit 2c3686882c
5 changed files with 272 additions and 28 deletions
+2
View File
@@ -147,6 +147,8 @@ static void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
bool is_lvgl_evt = evt_to_indev_data(evt, data);
if (!is_lvgl_evt) {
auto w = (Window*)lv_obj_get_user_data(obj);
// If no window, check for keyboard window
if (!w) w = Keyboard::keyboardWindow();
dispatch_kb_event(w, evt);
return;
}
+2
View File
@@ -31,6 +31,8 @@ class Keyboard : public Window
void clearField(bool wasCancelled);
static void hide(bool wasCancelled);
static Keyboard* keyboardWindow() { return activeKeyboard; }
protected:
static Keyboard *activeKeyboard;
+129 -18
View File
@@ -17,35 +17,34 @@
*/
#include "keyboard_number.h"
#include "numberedit.h"
constexpr coord_t KEYBOARD_HEIGHT = 90;
NumberKeyboard * NumberKeyboard::_instance = nullptr;
NumberKeyboard* NumberKeyboard::_instance = nullptr;
static const char* const number_kb_map[] = {
"<<", "-", "+", ">>", "\n",
"MIN", "DEF", "+/-", "MAX", ""
};
static const char* const number_kb_map[] = {"<<", "-", "+", ">>", "\n",
"MIN", "DEF", "+/-", "MAX", ""};
#define LV_KB_BTN(width) LV_BTNMATRIX_CTRL_POPOVER | width
#define LV_KB_CTRL(width) LV_KEYBOARD_CTRL_BTN_FLAGS | width
static const lv_btnmatrix_ctrl_t number_kb_ctrl_map[] = {
LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4),
LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_CTRL(4), LV_KB_BTN(4)
};
LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_CTRL(4), LV_KB_BTN(4)};
static void on_key(lv_event_t* e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_obj_t* obj = lv_event_get_target(e);
NumberEdit* edit = (NumberEdit*)lv_event_get_user_data(e);
if (!obj || !edit) return;
uint16_t btn_id = lv_btnmatrix_get_selected_btn(obj);
if(btn_id == LV_BTNMATRIX_BTN_NONE) return;
if (btn_id == LV_BTNMATRIX_BTN_NONE) return;
const char * txt = lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj));
if(txt == NULL) return;
const char* txt =
lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj));
if (txt == NULL) return;
if (strcmp(txt, "<<") == 0) {
edit->onEvent(EVT_VIRTUAL_KEY_BACKWARD);
@@ -66,8 +65,123 @@ static void on_key(lv_event_t* e)
}
}
NumberKeyboard::NumberKeyboard() :
Keyboard(KEYBOARD_HEIGHT)
#if defined(HARDWARE_KEYS)
void NumberKeyboard::onEvent(event_t event)
{
NumberEdit* edit = (NumberEdit*)field;
#if (defined(KEYS_GPIO_REG_PAGEUP) || defined(USE_HATS_AS_KEYS)) && !defined(PCBX12S)
// Radios with both PGUP and PGDN buttons except X12S
switch (event) {
case EVT_KEY_BREAK(KEY_SYS):
// "<<"
edit->onEvent(EVT_VIRTUAL_KEY_BACKWARD);
break;
case EVT_KEY_LONG(KEY_SYS):
killEvents(event);
// "MIN"
edit->onEvent(EVT_VIRTUAL_KEY_MIN);
break;
case EVT_KEY_BREAK(KEY_MODEL):
// ">>"
edit->onEvent(EVT_VIRTUAL_KEY_FORWARD);
break;
case EVT_KEY_LONG(KEY_MODEL):
killEvents(event);
// "MAX"
edit->onEvent(EVT_VIRTUAL_KEY_MAX);
break;
case EVT_KEY_BREAK(KEY_PAGEDN):
// "+"
edit->onEvent(EVT_VIRTUAL_KEY_PLUS);
break;
case EVT_KEY_BREAK(KEY_PAGEUP):
// "-"
edit->onEvent(EVT_VIRTUAL_KEY_MINUS);
break;
case EVT_KEY_BREAK(KEY_TELE):
// "+/-"
edit->onEvent(EVT_VIRTUAL_KEY_SIGN);
break;
case EVT_KEY_LONG(KEY_TELE):
killEvents(event);
// "DEF"
edit->onEvent(EVT_VIRTUAL_KEY_DEFAULT);
break;
default:
break;
}
#else
// Radios witb only a single PGUP/DN button or X12S
switch (event) {
case EVT_KEY_BREAK(KEY_SYS):
// "-"
edit->onEvent(EVT_VIRTUAL_KEY_MINUS);
break;
case EVT_KEY_LONG(KEY_SYS):
killEvents(event);
// "MIN"
edit->onEvent(EVT_VIRTUAL_KEY_MIN);
break;
case EVT_KEY_BREAK(KEY_MODEL):
// ">>"
edit->onEvent(EVT_VIRTUAL_KEY_FORWARD);
break;
case EVT_KEY_LONG(KEY_MODEL):
killEvents(event);
// "+/-"
edit->onEvent(EVT_VIRTUAL_KEY_SIGN);
break;
#if defined(PCBX12S)
case EVT_KEY_BREAK(KEY_PAGEUP):
#endif
case EVT_KEY_BREAK(KEY_PAGEDN):
// "<<"
edit->onEvent(EVT_VIRTUAL_KEY_BACKWARD);
break;
#if defined(PCBX12S)
case EVT_KEY_LONG(KEY_PAGEUP):
#endif
case EVT_KEY_LONG(KEY_PAGEDN):
killEvents(event);
// "DEF"
edit->onEvent(EVT_VIRTUAL_KEY_DEFAULT);
break;
case EVT_KEY_BREAK(KEY_TELE):
// "+"
edit->onEvent(EVT_VIRTUAL_KEY_PLUS);
break;
case EVT_KEY_LONG(KEY_TELE):
killEvents(event);
// "MAX"
edit->onEvent(EVT_VIRTUAL_KEY_MAX);
break;
default:
break;
}
#endif
}
#endif
NumberKeyboard::NumberKeyboard() : Keyboard(KEYBOARD_HEIGHT)
{
// setup custom keyboard
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1,
@@ -76,15 +190,12 @@ NumberKeyboard::NumberKeyboard() :
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
}
NumberKeyboard::~NumberKeyboard()
{
_instance = nullptr;
}
NumberKeyboard::~NumberKeyboard() { _instance = nullptr; }
void NumberKeyboard::show(NumberEdit* field)
{
if (!_instance) _instance = new NumberKeyboard();
lv_obj_clear_flag(_instance->lvobj, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(_instance->keyboard, LV_OBJ_FLAG_HIDDEN);
+4
View File
@@ -35,5 +35,9 @@ class NumberKeyboard : public Keyboard
static void show(NumberEdit* field);
protected:
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
static NumberKeyboard* _instance;
};
+135 -10
View File
@@ -17,25 +17,150 @@
*/
#include "keyboard_text.h"
#include "textedit.h"
#include "font.h"
#include "textedit.h"
constexpr coord_t KEYBOARD_HEIGHT = LCD_H * 2 / 5;
TextKeyboard * TextKeyboard::_instance = nullptr;
TextKeyboard* TextKeyboard::_instance = nullptr;
TextKeyboard::TextKeyboard() :
Keyboard(KEYBOARD_HEIGHT)
{
}
TextKeyboard::TextKeyboard() : Keyboard(KEYBOARD_HEIGHT) {}
TextKeyboard::~TextKeyboard()
{
_instance = nullptr;
}
TextKeyboard::~TextKeyboard() { _instance = nullptr; }
#if defined(HARDWARE_KEYS)
void TextKeyboard::onEvent(event_t event)
{
lv_keyboard_t* kb = (lv_keyboard_t*)keyboard;
#if (defined(KEYS_GPIO_REG_PAGEUP) || defined(USE_HATS_AS_KEYS)) && !defined(PCBX12S)
// Radios with both PGUP and PGDN buttons except X12S
switch (event) {
case EVT_KEY_BREAK(KEY_SYS): {
// Change keyboard mode
lv_keyboard_mode_t mode = lv_keyboard_get_mode(keyboard);
mode = (mode + 1) & 3;
lv_keyboard_set_mode(keyboard, mode);
} break;
case EVT_KEY_LONG(KEY_MODEL):
killEvents(event);
// Backspace
lv_textarea_del_char(kb->ta);
break;
case EVT_KEY_BREAK(KEY_PAGEDN):
// Cursor right
lv_textarea_cursor_right(kb->ta);
break;
case EVT_KEY_BREAK(KEY_PAGEUP):
// Cursor left
lv_textarea_cursor_left(kb->ta);
break;
case EVT_KEY_LONG(KEY_PAGEDN): {
killEvents(event);
// Cursor to end
int l = strlen(lv_textarea_get_text(kb->ta));
while (lv_textarea_get_cursor_pos(kb->ta) < l)
lv_textarea_cursor_right(kb->ta);
} break;
case EVT_KEY_LONG(KEY_PAGEUP):
killEvents(event);
// Cursor to start
while (lv_textarea_get_cursor_pos(kb->ta) > 0)
lv_textarea_cursor_left(kb->ta);
break;
case EVT_KEY_BREAK(KEY_TELE): {
// Toggle case
char c = lv_textarea_get_text(kb->ta)[lv_textarea_get_cursor_pos(kb->ta)];
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) {
c ^= 0x20;
lv_textarea_del_char_forward(kb->ta);
lv_textarea_add_char(kb->ta, c);
lv_textarea_cursor_left(kb->ta);
}
} break;
case EVT_KEY_LONG(KEY_TELE):
killEvents(event);
// Delete
lv_textarea_del_char_forward(kb->ta);
break;
default:
break;
}
#else
// Radios witb only a single PGUP/DN button or X12S
switch (event) {
case EVT_KEY_BREAK(KEY_SYS):
// Cursor left
lv_textarea_cursor_left(kb->ta);
break;
case EVT_KEY_LONG(KEY_SYS):
killEvents(event);
// Cursor to start
while (lv_textarea_get_cursor_pos(kb->ta) > 0)
lv_textarea_cursor_left(kb->ta);
break;
case EVT_KEY_BREAK(KEY_MODEL): {
// Change keyboard mode
lv_keyboard_mode_t mode = lv_keyboard_get_mode(keyboard);
mode = (mode + 1) & 3;
lv_keyboard_set_mode(keyboard, mode);
} break;
case EVT_KEY_LONG(KEY_MODEL):
killEvents(event);
// Backspace
lv_textarea_del_char(kb->ta);
break;
#if defined(PCBX12S)
case EVT_KEY_BREAK(KEY_PAGEUP):
#endif
case EVT_KEY_BREAK(KEY_PAGEDN): {
// Toggle case
char c = lv_textarea_get_text(kb->ta)[lv_textarea_get_cursor_pos(kb->ta)];
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) {
c ^= 0x20;
lv_textarea_del_char_forward(kb->ta);
lv_textarea_add_char(kb->ta, c);
lv_textarea_cursor_left(kb->ta);
}
} break;
case EVT_KEY_LONG(KEY_PAGEDN):
killEvents(event);
// Delete
lv_textarea_del_char_forward(kb->ta);
break;
case EVT_KEY_BREAK(KEY_TELE): {
// Cursor right
lv_textarea_cursor_right(kb->ta);
} break;
case EVT_KEY_LONG(KEY_TELE): {
killEvents(event);
// Cursor to end
int l = strlen(lv_textarea_get_text(kb->ta));
while (lv_textarea_get_cursor_pos(kb->ta) < l)
lv_textarea_cursor_right(kb->ta);
} break;
default:
break;
}
#endif
}
#endif