mirror of
https://github.com/lvgl/lvgl.git
synced 2026-09-23 03:35:30 +08:00
feat(indev): implement key remapping (#8455) (#8981)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Co-authored-by: Jean THOMAS <jean@lambdaconcept.com>
This commit is contained in:
co-authored by
Jean THOMAS
parent
262a125dac
commit
cf38b6f873
@@ -87,3 +87,41 @@ The most important special keys in your :cpp:func:`read_cb` function are:
|
||||
|
||||
You should translate some of the read keys to these special keys to support navigation
|
||||
in a group and interact with selected widgets.
|
||||
|
||||
Key remapping
|
||||
*************
|
||||
|
||||
Some applications require assigning physical buttons to multiple key events depending
|
||||
on the context: arrow keys may be used in a screen to navigate across widgets, and
|
||||
used to interact with one widget in another screen. Key remapping functionality of
|
||||
indev can be used to implement this behavior.
|
||||
|
||||
You must first define a remapping callback, then invoke
|
||||
:cpp:func:`lv_indev_set_key_remap_cb` to enable it.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
lv_key_t remap_left_right_into_prev_next(lv_indev_t * indev, lv_key_t key)
|
||||
{
|
||||
LV_UNUSED(indev);
|
||||
|
||||
switch (key) {
|
||||
case LV_KEY_LEFT:
|
||||
return LV_KEY_PREV;
|
||||
case LV_KEY_RIGHT:
|
||||
return LV_KEY_NEXT;
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* in your setup code */
|
||||
lv_indev_set_key_remap_cb(indev, remap_left_right_into_prev_next);
|
||||
|
||||
/* later, to disable remapping */
|
||||
lv_indev_set_key_remap_cb(indev, NULL);
|
||||
|
||||
.. note::
|
||||
The remap callback is invoked only for keypad input devices. It will not remap keys from other input device types.
|
||||
|
||||
@@ -141,6 +141,7 @@ lv_indev_t * lv_indev_create(void)
|
||||
indev->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
|
||||
indev->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY;
|
||||
indev->rotary_sensitivity = LV_INDEV_DEF_ROTARY_SENSITIVITY;
|
||||
indev->key_remap_cb = NULL;
|
||||
|
||||
#if LV_USE_GESTURE_RECOGNITION
|
||||
lv_indev_gesture_init(indev);
|
||||
@@ -674,6 +675,16 @@ lv_result_t lv_indev_send_event(lv_indev_t * indev, lv_event_code_t code, void *
|
||||
return lv_event_push_and_send(&indev->event_list, code, indev, param);
|
||||
}
|
||||
|
||||
void lv_indev_set_key_remap_cb(lv_indev_t * indev, lv_indev_key_remap_cb_t remap_cb)
|
||||
{
|
||||
if(!indev) {
|
||||
LV_LOG_WARN("Can't remap key on a NULL indev");
|
||||
return;
|
||||
}
|
||||
|
||||
indev->key_remap_cb = remap_cb;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -762,6 +773,11 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
i->keypad.last_state = LV_INDEV_STATE_RELEASED; /*To skip the processing of release*/
|
||||
}
|
||||
|
||||
/* Remap key using callback */
|
||||
if(i->key_remap_cb) {
|
||||
data->key = i->key_remap_cb(i, data->key);
|
||||
}
|
||||
|
||||
/*Save the last key. *It must be done here else `lv_indev_get_key` will return the last key in events*/
|
||||
uint32_t prev_key = i->keypad.last_key;
|
||||
i->keypad.last_key = data->key;
|
||||
|
||||
@@ -77,6 +77,9 @@ typedef struct {
|
||||
|
||||
typedef void (*lv_indev_read_cb_t)(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/** Indev key remapping callback */
|
||||
typedef lv_key_t (*lv_indev_key_remap_cb_t)(lv_indev_t * indev, lv_key_t key);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -442,6 +445,13 @@ uint32_t lv_indev_remove_event_cb_with_user_data(lv_indev_t * indev, lv_event_cb
|
||||
*/
|
||||
lv_result_t lv_indev_send_event(lv_indev_t * indev, lv_event_code_t code, void * param);
|
||||
|
||||
/**
|
||||
* Set key remapping callback (LV_INDEV_TYPE_KEYPAD)
|
||||
* @param indev pointer to an indev
|
||||
* @param remap_cb remapping function callback. Use NULL to disable callback.
|
||||
*/
|
||||
void lv_indev_set_key_remap_cb(lv_indev_t * indev, lv_indev_key_remap_cb_t remap_cb);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -123,6 +123,9 @@ struct _lv_indev_t {
|
||||
lv_event_list_t event_list;
|
||||
lv_anim_t * scroll_throw_anim;
|
||||
|
||||
/**< Key remapping callback */
|
||||
lv_indev_key_remap_cb_t key_remap_cb;
|
||||
|
||||
#if LV_USE_GESTURE_RECOGNITION
|
||||
lv_indev_gesture_recognizer_t recognizers[LV_INDEV_GESTURE_CNT];
|
||||
lv_indev_gesture_type_t cur_gesture;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
#include "unity/unity.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define MAX_KEYS 6
|
||||
|
||||
struct key_buffer {
|
||||
size_t count;
|
||||
lv_key_t keys[MAX_KEYS];
|
||||
};
|
||||
|
||||
static void key_buffer_add(struct key_buffer * key_buffer, lv_key_t key)
|
||||
{
|
||||
assert(key_buffer->count + 1 <= MAX_KEYS);
|
||||
|
||||
key_buffer->keys[key_buffer->count++] = key;
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
/* Function run before every test */
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
/* Function run after every test */
|
||||
lv_obj_clean(lv_screen_active());
|
||||
}
|
||||
|
||||
static void event_cb(lv_event_t * e)
|
||||
{
|
||||
struct key_buffer * key_buffer = lv_event_get_user_data(e);
|
||||
|
||||
switch(lv_event_get_code(e)) {
|
||||
case LV_EVENT_KEY:
|
||||
key_buffer_add(key_buffer, lv_indev_get_key(lv_indev_active()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static lv_key_t remap_cb(lv_indev_t * i, lv_key_t key)
|
||||
{
|
||||
LV_UNUSED(i);
|
||||
|
||||
switch((int)key) {
|
||||
case 'a':
|
||||
return LV_KEY_LEFT;
|
||||
case LV_KEY_ESC:
|
||||
return 'Z';
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
void test_indev_key_remap(void)
|
||||
{
|
||||
struct key_buffer key_buffer = {
|
||||
.count = 0,
|
||||
};
|
||||
|
||||
lv_group_t * group = lv_group_create();
|
||||
lv_indev_t * indev = lv_test_indev_get_indev(LV_INDEV_TYPE_KEYPAD);
|
||||
lv_indev_set_group(indev, group);
|
||||
|
||||
lv_obj_t * btn = lv_button_create(lv_screen_active());
|
||||
lv_obj_set_size(btn, 100, 100);
|
||||
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, &key_buffer);
|
||||
lv_group_add_obj(group, btn);
|
||||
|
||||
lv_test_key_hit('a');
|
||||
lv_test_key_hit(LV_KEY_ESC);
|
||||
|
||||
/* Remap 'a' -> LV_KEY_LEFT, LV_KEY_ESC -> 'Z' */
|
||||
|
||||
lv_indev_set_key_remap_cb(indev, remap_cb);
|
||||
|
||||
lv_test_key_hit('a');
|
||||
lv_test_key_hit(LV_KEY_ESC);
|
||||
|
||||
/* Disable remapping */
|
||||
|
||||
lv_indev_set_key_remap_cb(indev, NULL);
|
||||
|
||||
lv_test_key_hit('a');
|
||||
lv_test_key_hit(LV_KEY_ESC);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(6, key_buffer.count);
|
||||
TEST_ASSERT_EQUAL_UINT32('a', key_buffer.keys[0]);
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_KEY_ESC, key_buffer.keys[1]);
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_KEY_LEFT, key_buffer.keys[2]);
|
||||
TEST_ASSERT_EQUAL_UINT32('Z', key_buffer.keys[3]);
|
||||
TEST_ASSERT_EQUAL_UINT32('a', key_buffer.keys[4]);
|
||||
TEST_ASSERT_EQUAL_UINT32(LV_KEY_ESC, key_buffer.keys[5]);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user