Input device interface¶
Types of input devices¶
To set up an input device an lv_indev_drv_t
variable has to be initialized:
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type =... /*See below.*/
indev_drv.read_cb =... /*See below.*/
/*Register the driver in LVGL and save the created input device object*/
lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
type can be
LV_INDEV_TYPE_POINTER touchpad or mouse
LV_INDEV_TYPE_KEYPAD keyboard or keypad
LV_INDEV_TYPE_ENCODER encoder with left, right, push options
LV_INDEV_TYPE_BUTTON external buttons pressing the screen
read_cb is a function pointer which will be called periodically to report the current state of an input device.
It can also buffer data and return false
when no more data to be read or true
when the buffer is not empty.
Visit Input devices to learn more about input devices in general.
Touchpad, mouse or any pointer¶
Input devices which can click points of the screen belong to this category.
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_input_read;
...
bool my_input_read(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
data->point.x = touchpad_x;
data->point.y = touchpad_y;
data->state = LV_INDEV_STATE_PR or LV_INDEV_STATE_REL;
return false; /*No buffering now so no more data read*/
}
Important
Touchpad drivers must return the last X/Y coordinates even when the state is LV_INDEV_STATE_REL.
To set a mouse cursor use lv_indev_set_cursor(my_indev, &img_cursor)
. (my_indev
is the return value of lv_indev_drv_register
)
Keypad or keyboard¶
Full keyboards with all the letters or simple keypads with a few navigation buttons belong here.
To use a keyboard/keypad:
Register a
read_cb
function withLV_INDEV_TYPE_KEYPAD
type.Enable
LV_USE_GROUP
in lv_conf.hAn object group has to be created:
lv_group_t * g = lv_group_create()
and objects have to be added to it withlv_group_add_obj(g, obj)
The created group has to be assigned to an input device:
lv_indev_set_group(my_indev, g)
(my_indev
is the return value oflv_indev_drv_register
)Use
LV_KEY_...
to navigate among the objects in the group. Seelv_core/lv_group.h
for the available keys.
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keyboard_read;
...
bool keyboard_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->key = last_key(); /*Get the last pressed or released key*/
if(key_pressed()) data->state = LV_INDEV_STATE_PR;
else data->state = LV_INDEV_STATE_REL;
return false; /*No buffering now so no more data read*/
}
Encoder¶
With an encoder you can do 4 things:
Press its button
Long-press its button
Turn left
Turn right
In short, the Encoder input devices work like this:
By turning the encoder you can focus on the next/previous object.
When you press the encoder on a simple object (like a button), it will be clicked.
If you press the encoder on a complex object (like a list, message box, etc.) the object will go to edit mode whereby turning the encoder you can navigate inside the object.
To leave edit mode press long the button.
To use an Encoder (similarly to the Keypads) the objects should be added to groups.
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_read;
...
bool encoder_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->enc_diff = enc_get_new_moves();
if(enc_pressed()) data->state = LV_INDEV_STATE_PR;
else data->state = LV_INDEV_STATE_REL;
return false; /*No buffering now so no more data read*/
}
Using buttons with Encoder logic¶
In addition to standard encoder behavior, you can also utilise its logic to navigate(focus) and edit widgets using buttons. This is especially handy if you have only few buttons avalible, or you want to use other buttons in addition to encoder wheel.
You need to have 3 buttons avalible:
LV_KEY_ENTER will simulate press or pushing of the encoder button
LV_KEY_LEFT will simulate turnuing encoder left
LV_KEY_RIGHT will simulate turnuing encoder right
other keys will be passed to the focused widget
If you hold the keys it will simulate encoder click with period specified in indev_drv.long_press_rep_time
.
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_with_keys_read;
...
bool encoder_with_keys_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
data->key = last_key(); /*Get the last pressed or released key*/
/* use LV_KEY_ENTER for encoder press */
if(key_pressed()) data->state = LV_INDEV_STATE_PR;
else {
data->state = LV_INDEV_STATE_REL;
/* Optionally you can also use enc_diff, if you have encoder*/
data->enc_diff = enc_get_new_moves();
}
return false; /*No buffering now so no more data read*/
}
Button¶
Buttons mean external "hardware" buttons next to the screen which are assigned to specific coordinates of the screen. If a button is pressed it will simulate the pressing on the assigned coordinate. (Similarly to a touchpad)
To assign buttons to coordinates use lv_indev_set_button_points(my_indev, points_array)
.points_array
should look like const lv_point_t points_array[] = { {12,30},{60,90}, ...}
Important
The points_array can't go out of scope. Either declare it as a global variable or as a static variable inside a function.
indev_drv.type = LV_INDEV_TYPE_BUTTON;
indev_drv.read_cb = button_read;
...
bool button_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
static uint32_t last_btn = 0; /*Store the last pressed button*/
int btn_pr = my_btn_read(); /*Get the ID (0,1,2...) of the pressed button*/
if(btn_pr >= 0) { /*Is there a button press? (E.g. -1 indicated no button was pressed)*/
last_btn = btn_pr; /*Save the ID of the pressed button*/
data->state = LV_INDEV_STATE_PR; /*Set the pressed state*/
} else {
data->state = LV_INDEV_STATE_REL; /*Set the released state*/
}
data->btn = last_btn; /*Save the last button*/
return false; /*No buffering now so no more data read*/
}
Other features¶
Besides read_cb
a feedback_cb
callback can be also specified in lv_indev_drv_t
.
feedback_cb
is called when any type of event is sent by the input devices. (independently from its type). It allows making feedback for the user e.g. to play a sound on LV_EVENT_CLICK
.
The default value of the following parameters can be set in lv_conf.h but the default value can be overwritten in lv_indev_drv_t
:
drag_limit Number of pixels to slide before actually drag the object
drag_throw Drag throw slow-down in [%]. Greater value means faster slow-down
long_press_time Press time to send
LV_EVENT_LONG_PRESSED
(in milliseconds)long_press_rep_time Interval of sending
LV_EVENT_LONG_PRESSED_REPEAT
(in milliseconds)read_task pointer to the
lv_task
which reads the input device. Its parameters can be changed bylv_task_...()
functions
Every Input device is associated with a display. By default, a new input device is added to the lastly created or the explicitly selected (using lv_disp_set_default()
) display.
The associated display is stored and can be changed in disp
field of the driver.
API¶
Input Device HAL interface layer header file
Typedefs
-
typedef uint8_t
lv_indev_type_t
¶
-
typedef uint8_t
lv_indev_state_t
¶
-
typedef uint8_t
lv_drag_dir_t
¶
-
typedef uint8_t
lv_gesture_dir_t
¶
-
typedef struct _lv_indev_drv_t
lv_indev_drv_t
¶ Initialized by the user and registered by 'lv_indev_add()'
-
typedef struct _lv_indev_proc_t
lv_indev_proc_t
¶ Run time data of input devices Internally used by the library, you should not need to touch it.
-
typedef struct _lv_indev_t
lv_indev_t
¶ The main input device descriptor with driver, runtime data ('proc') and some additional information
Enums
-
enum [anonymous]¶
Possible input device types
Values:
-
enumerator
LV_INDEV_TYPE_NONE
¶ Uninitialized state
-
enumerator
LV_INDEV_TYPE_POINTER
¶ Touch pad, mouse, external button
-
enumerator
LV_INDEV_TYPE_KEYPAD
¶ Keypad or keyboard
-
enumerator
LV_INDEV_TYPE_BUTTON
¶ External (hardware button) which is assigned to a specific point of the screen
-
enumerator
LV_INDEV_TYPE_ENCODER
¶ Encoder with only Left, Right turn and a Button
-
enumerator
-
enum [anonymous]¶
States for input devices
Values:
-
enumerator
LV_INDEV_STATE_REL
¶
-
enumerator
LV_INDEV_STATE_PR
¶
-
enumerator
-
enum [anonymous]¶
Values:
-
enumerator
LV_DRAG_DIR_HOR
¶ Object can be dragged horizontally.
-
enumerator
LV_DRAG_DIR_VER
¶ Object can be dragged vertically.
-
enumerator
LV_DRAG_DIR_BOTH
¶ Object can be dragged in all directions.
-
enumerator
LV_DRAG_DIR_ONE
¶ Object can be dragged only one direction (the first move).
-
enumerator
Functions
-
void
lv_indev_drv_init
(lv_indev_drv_t *driver)¶ Initialize an input device driver with default values. It is used to surly have known values in the fields ant not memory junk. After it you can set the fields.
- Parameters
driver -- pointer to driver variable to initialize
-
lv_indev_t *
lv_indev_drv_register
(lv_indev_drv_t *driver)¶ Register an initialized input device driver.
- Parameters
driver -- pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
- Returns
pointer to the new input device or NULL on error
-
void
lv_indev_drv_update
(lv_indev_t *indev, lv_indev_drv_t *new_drv)¶ Update the driver in run time.
- Parameters
indev -- pointer to a input device. (return value of
lv_indev_drv_register
)new_drv -- pointer to the new driver
-
lv_indev_t *
lv_indev_get_next
(lv_indev_t *indev)¶ Get the next input device.
- Parameters
indev -- pointer to the current input device. NULL to initialize.
- Returns
the next input devise or NULL if no more. Give the first input device when the parameter is NULL
-
bool
_lv_indev_read
(lv_indev_t *indev, lv_indev_data_t *data)¶ Read data from an input device.
- Parameters
indev -- pointer to an input device
data -- input device will write its data here
- Returns
false: no more data; true: there more data to read (buffered)
-
struct
lv_indev_data_t
¶ - #include <lv_hal_indev.h>
Data structure passed to an input driver to fill
Public Members
-
lv_point_t
point
¶ For LV_INDEV_TYPE_POINTER the currently pressed point
-
uint32_t
key
¶ For LV_INDEV_TYPE_KEYPAD the currently pressed key
-
uint32_t
btn_id
¶ For LV_INDEV_TYPE_BUTTON the currently pressed button
-
int16_t
enc_diff
¶ For LV_INDEV_TYPE_ENCODER number of steps since the previous read
-
lv_indev_state_t
state
¶ LV_INDEV_STATE_REL or LV_INDEV_STATE_PR
-
lv_point_t
-
struct
_lv_indev_drv_t
¶ - #include <lv_hal_indev.h>
Initialized by the user and registered by 'lv_indev_add()'
Public Members
-
lv_indev_type_t
type
¶ < Input device type Function pointer to read input device data. Return 'true' if there is more data to be read (buffered). Most drivers can safely return 'false'
-
bool (*
read_cb
)(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data)¶
-
void (*
feedback_cb
)(struct _lv_indev_drv_t*, uint8_t)¶ Called when an action happened on the input device. The second parameter is the event from
lv_event_t
-
lv_indev_drv_user_data_t
user_data
¶
-
struct _disp_t *
disp
¶ < Pointer to the assigned display Task to read the periodically read the input device
-
uint8_t
drag_limit
¶ Drag throw slow-down in [%]. Greater value means faster slow-down
-
uint8_t
drag_throw
¶ At least this difference should between two points to evaluate as gesture
-
uint8_t
gesture_min_velocity
¶ At least this difference should be to send a gesture
-
uint8_t
gesture_limit
¶ Long press time in milliseconds
-
uint16_t
long_press_time
¶ Repeated trigger period in long press [ms]
-
uint16_t
long_press_rep_time
¶
-
lv_indev_type_t
-
struct
_lv_indev_proc_t
¶ - #include <lv_hal_indev.h>
Run time data of input devices Internally used by the library, you should not need to touch it.
Public Members
-
lv_indev_state_t
state
¶ Current state of the input device.
-
lv_point_t
act_point
¶ Current point of input device.
-
lv_point_t
last_point
¶ Last point of input device.
-
lv_point_t
vect
¶ Difference between
act_point
andlast_point
.
-
lv_point_t
drag_sum
¶
-
lv_point_t
drag_throw_vect
¶
-
lv_gesture_dir_t
gesture_dir
¶
-
lv_point_t
gesture_sum
¶
-
uint8_t
drag_limit_out
¶
-
uint8_t
drag_in_prog
¶
-
lv_drag_dir_t
drag_dir
¶
-
uint8_t
gesture_sent
¶
-
struct _lv_indev_proc_t::[anonymous]::[anonymous]
pointer
¶
-
lv_indev_state_t
last_state
¶
-
uint32_t
last_key
¶
-
struct _lv_indev_proc_t::[anonymous]::[anonymous]
keypad
¶
-
union _lv_indev_proc_t::[anonymous]
types
¶
-
uint32_t
pr_timestamp
¶ Pressed time stamp
-
uint32_t
longpr_rep_timestamp
¶ Long press repeat time stamp
-
uint8_t
long_pr_sent
¶
-
uint8_t
reset_query
¶
-
uint8_t
disabled
¶
-
uint8_t
wait_until_release
¶
-
lv_indev_state_t
-
struct
_lv_indev_t
¶ - #include <lv_hal_indev.h>
The main input device descriptor with driver, runtime data ('proc') and some additional information
Public Members
-
lv_indev_drv_t
driver
¶
-
lv_indev_proc_t
proc
¶
-
struct _lv_group_t *
group
¶ Keypad destination group
-
const lv_point_t *
btn_points
¶ Array points assigned to the button ()screen will be pressed here by the buttons
-
lv_indev_drv_t