输入设备

输入设备通常指:

  • 类似指针的输入设备,例如触摸板或鼠标

  • 键盘,例如普通键盘或简单的数字键盘

  • 编码器,具有左右旋转和按压选项

  • 外部硬件按钮,这些按钮分配到屏幕上的特定点

Important

在继续阅读之前,请先阅读输入设备的[移植](/porting/indev)部分。

指针

光标

指针输入设备(例如鼠标)可以有一个光标。

...
lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv);

LV_IMG_DECLARE(mouse_cursor_icon);                          /* 声明图像资源 */
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act());       /* 为光标创建一个图像对象 */
lv_img_set_src(cursor_obj, &mouse_cursor_icon);             /* 设置图像资源 */
lv_indev_set_cursor(mouse_indev, cursor_obj);               /* 将图像对象连接到驱动程序 */

注意,光标对象应设置为 lv_obj_clear_flag(cursor_obj, LV_OBJ_FLAG_CLICKABLE)。 对于图像,点击 默认是禁用的。

手势

指针输入设备可以检测基本手势。默认情况下,大多数小部件会将手势传递给其父对象,因此最终可以在屏幕对象上以 LV_EVENT_GESTURE 事件的形式检测到手势。例如:

void my_event(lv_event_t * e)
{
  lv_obj_t * screen = lv_event_get_current_target(e);
  lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_act());
  switch(dir) {
    case LV_DIR_LEFT:
      ...
      break;
    case LV_DIR_RIGHT:
      ...
      break;
    case LV_DIR_TOP:
      ...
      break;
    case LV_DIR_BOTTOM:
      ...
      break;
  }
}

...

lv_obj_add_event_cb(screen1, my_event, LV_EVENT_GESTURE, NULL);

要阻止手势事件从对象传递到父对象,可以使用 lv_obj_clear_flag(obj, LV_OBJ_FLAG_GESTURE_BUBBLE)

注意,如果一个对象正在滚动,则不会触发手势。

如果您在手势上执行了一些操作,可以在事件处理程序中调用 lv_indev_wait_release(lv_indev_get_act()),以防止 LVGL 发送进一步的输入设备相关事件。

键盘和编码器

您可以完全使用键盘或编码器控制用户界面,而无需触摸板或鼠标。这类似于 PC 上的 TAB 键,用于选择应用程序或网页中的元素。

您希望通过键盘或编码器控制的对象需要添加到一个 中。 在每个组中,只有一个聚焦对象会接收按下的键或编码器的操作。 例如,如果一个 文本区域 被聚焦,并且您在键盘上按下一些字母,这些键将被发送并插入到文本区域中。 类似地,如果一个 滑块 被聚焦,并且您按下左箭头或右箭头,滑块的值将会改变。

您需要将输入设备与组关联。一个输入设备只能向一个组发送键事件,但一个组可以接收来自多个输入设备的数据。

要创建一个组,请使用 lv_group_t * g = lv_group_create(),并使用 lv_group_add_obj(g, obj) 将对象添加到组中。

要将组与输入设备关联,请使用 lv_indev_set_group(indev, g),其中 indevlv_indev_drv_register() 的返回值。

有一些预定义的键具有特殊含义:

  • LV_KEY_NEXT 聚焦下一个对象

  • LV_KEY_PREV 聚焦上一个对象

  • LV_KEY_ENTER 触发 LV_EVENT_PRESSED/CLICKED/LONG_PRESSED 等事件

  • LV_KEY_UP 增加值或向上移动

  • LV_KEY_DOWN 减少值或向下移动

  • LV_KEY_RIGHT 增加值或向右移动

  • LV_KEY_LEFT 减少值或向左移动

  • LV_KEY_ESC 关闭或退出(例如,关闭一个 下拉列表

  • LV_KEY_DEL 删除(例如,文本区域 中右侧的字符)

  • LV_KEY_BACKSPACE 删除左侧的字符(例如,在 文本区域 中)

  • LV_KEY_HOME 转到开头/顶部(例如,在 文本区域 中)

  • LV_KEY_END 转到末尾(例如,在 文本区域 中)

最重要的特殊键是 LV_KEY_NEXT/PREVLV_KEY_ENTERLV_KEY_UP/DOWN/LEFT/RIGHT。 在您的 read_cb 函数中,您应该将一些键转换为这些特殊键,以支持组中的导航并与选定对象交互。

通常,仅使用 LV_KEY_LEFT/RIGHT 就足够了,因为大多数对象可以通过它们完全控制。

对于编码器,您应该仅使用 LV_KEY_LEFTLV_KEY_RIGHTLV_KEY_ENTER

编辑和导航模式

由于键盘有很多键,因此可以轻松地在对象之间导航并使用键盘编辑它们。但编码器的“键”数量有限,因此使用默认选项导航较为困难。导航编辑 模式用于解决编码器的这个问题。

导航 模式下,编码器的 LV_KEY_LEFT/RIGHT 被转换为 LV_KEY_NEXT/PREV。因此,通过旋转编码器,可以选择下一个或上一个对象。 按下 LV_KEY_ENTER 将切换到 编辑 模式。

编辑 模式下,LV_KEY_NEXT/PREV 通常用于修改对象。 根据对象的类型,短按或长按 LV_KEY_ENTER 会切换回 导航 模式。 通常,无法按下的对象(例如 滑块)在短按时会退出 编辑 模式。但对于短按有意义的对象(例如 按钮),需要长按。

默认组

交互式小部件 - 例如按钮、复选框、滑块等 - 可以自动添加到默认组中。 只需使用 lv_group_t * g = lv_group_create(); 创建一个组,并使用 lv_group_set_default(g); 设置默认组。

不要忘记使用 lv_indev_set_group(my_indev, g); 将一个或多个输入设备分配到默认组。

样式

如果一个对象通过触摸板点击或通过编码器或键盘聚焦,它将进入 LV_STATE_FOCUSED 状态。因此,将应用聚焦样式。

如果一个对象切换到编辑模式,它将进入 LV_STATE_FOCUSED | LV_STATE_EDITED 状态,因此将显示这些样式属性。

有关更详细的描述,请阅读 样式 部分。

API

输入设备

Functions

void lv_indev_read_timer_cb(lv_timer_t *timer)

Called periodically to read the input devices

Parameters

timer -- pointer to a timer to read

void lv_indev_enable(lv_indev_t *indev, bool en)

Enable or disable one or all input devices (default enabled)

Parameters
  • indev -- pointer to an input device or NULL to enable/disable all of them

  • en -- true to enable, false to disable

lv_indev_t *lv_indev_get_act(void)

Get the currently processed input device. Can be used in action functions too.

Returns

pointer to the currently processed input device or NULL if no input device processing right now

lv_indev_type_t lv_indev_get_type(const lv_indev_t *indev)

Get the type of an input device

Parameters

indev -- pointer to an input device

Returns

the type of the input device from lv_hal_indev_type_t (LV_INDEV_TYPE_...)

void lv_indev_reset(lv_indev_t *indev, lv_obj_t *obj)

Reset one or all input devices

Parameters
  • indev -- pointer to an input device to reset or NULL to reset all of them

  • obj -- pointer to an object which triggers the reset.

void lv_indev_reset_long_press(lv_indev_t *indev)

Reset the long press state of an input device

Parameters

indev -- pointer to an input device

void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj)

Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)

Parameters
  • indev -- pointer to an input device

  • cur_obj -- pointer to an object to be used as cursor

void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group)

Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)

Parameters
  • indev -- pointer to an input device

  • group -- point to a group

void lv_indev_set_button_points(lv_indev_t *indev, const lv_point_t points[])

Set the an array of points for LV_INDEV_TYPE_BUTTON. These points will be assigned to the buttons to press a specific point on the screen

Parameters
  • indev -- pointer to an input device

  • group -- point to a group

void lv_indev_get_point(const lv_indev_t *indev, lv_point_t *point)

Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)

Parameters
  • indev -- pointer to an input device

  • point -- pointer to a point to store the result

lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t *indev)

Get the current gesture direct

Parameters

indev -- pointer to an input device

Returns

current gesture direct

uint32_t lv_indev_get_key(const lv_indev_t *indev)

Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)

Parameters

indev -- pointer to an input device

Returns

the last pressed key (0 on error)

lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t *indev)

Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)

Parameters

indev -- pointer to an input device

Returns

LV_DIR_NONE: no scrolling now LV_DIR_HOR/VER

lv_obj_t *lv_indev_get_scroll_obj(const lv_indev_t *indev)

Get the currently scrolled object (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)

Parameters

indev -- pointer to an input device

Returns

pointer to the currently scrolled object or NULL if no scrolling by this indev

void lv_indev_get_vect(const lv_indev_t *indev, lv_point_t *point)

Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)

Parameters
  • indev -- pointer to an input device

  • point -- pointer to a point to store the types.pointer.vector

void lv_indev_wait_release(lv_indev_t *indev)

Do nothing until the next release

Parameters

indev -- pointer to an input device

lv_obj_t *lv_indev_get_obj_act(void)

Gets a pointer to the currently active object in the currently processed input device.

Returns

pointer to currently active object or NULL if no active object

lv_timer_t *lv_indev_get_read_timer(lv_disp_t *indev)

Get a pointer to the indev read timer to modify its parameters with lv_timer_... functions.

Parameters

indev -- pointer to an input device

Returns

pointer to the indev read refresher timer. (NULL on error)

lv_obj_t *lv_indev_search_obj(lv_obj_t *obj, lv_point_t *point)

Search the most top, clickable object by a point

Parameters
  • obj -- pointer to a start object, typically the screen

  • point -- pointer to a point for searching the most top child

Returns

pointer to the found object or NULL if there was no suitable object

Typedefs

typedef uint8_t lv_key_t
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t*)
typedef void (*lv_group_edge_cb_t)(struct _lv_group_t*, bool)
typedef struct _lv_group_t lv_group_t

Groups can be used to logically hold objects so that they can be individually focused. They are NOT for laying out objects on a screen (try layouts for that).

Enums

Values:

enumerator LV_KEY_UP
enumerator LV_KEY_DOWN
enumerator LV_KEY_RIGHT
enumerator LV_KEY_LEFT
enumerator LV_KEY_ESC
enumerator LV_KEY_DEL
enumerator LV_KEY_BACKSPACE
enumerator LV_KEY_ENTER
enumerator LV_KEY_NEXT
enumerator LV_KEY_PREV
enumerator LV_KEY_HOME
enumerator LV_KEY_END
enum lv_group_refocus_policy_t

Values:

enumerator LV_GROUP_REFOCUS_POLICY_NEXT
enumerator LV_GROUP_REFOCUS_POLICY_PREV

Functions

void _lv_group_init(void)

Init. the group module

Remark

Internal function, do not call directly.

lv_group_t *lv_group_create(void)

Create a new object group

Returns

pointer to the new object group

void lv_group_del(lv_group_t *group)

Delete a group object

Parameters

group -- pointer to a group

void lv_group_set_default(lv_group_t *group)

Set a default group. New object are added to this group if it's enabled in their class with add_to_def_group = true

Parameters

group -- pointer to a group (can be NULL)

lv_group_t *lv_group_get_default(void)

Get the default group

Returns

pointer to the default group

void lv_group_add_obj(lv_group_t *group, struct _lv_obj_t *obj)

Add an object to a group

Parameters
  • group -- pointer to a group

  • obj -- pointer to an object to add

void lv_group_swap_obj(struct _lv_obj_t *obj1, struct _lv_obj_t *obj2)

Swap 2 object in a group. The object must be in the same group

Parameters
  • obj1 -- pointer to an object

  • obj2 -- pointer to an other object

void lv_group_remove_obj(struct _lv_obj_t *obj)

Remove an object from its group

Parameters

obj -- pointer to an object to remove

void lv_group_remove_all_objs(lv_group_t *group)

Remove all objects from a group

Parameters

group -- pointer to a group

void lv_group_focus_obj(struct _lv_obj_t *obj)

Focus on an object (defocus the current)

Parameters

obj -- pointer to an object to focus on

void lv_group_focus_next(lv_group_t *group)

Focus the next object in a group (defocus the current)

Parameters

group -- pointer to a group

void lv_group_focus_prev(lv_group_t *group)

Focus the previous object in a group (defocus the current)

Parameters

group -- pointer to a group

void lv_group_focus_freeze(lv_group_t *group, bool en)

Do not let to change the focus from the current object

Parameters
  • group -- pointer to a group

  • en -- true: freeze, false: release freezing (normal mode)

lv_res_t lv_group_send_data(lv_group_t *group, uint32_t c)

Send a control character to the focuses object of a group

Parameters
  • group -- pointer to a group

  • c -- a character (use LV_KEY_.. to navigate)

Returns

result of focused object in group.

void lv_group_set_focus_cb(lv_group_t *group, lv_group_focus_cb_t focus_cb)

Set a function for a group which will be called when a new object is focused

Parameters
  • group -- pointer to a group

  • focus_cb -- the call back function or NULL if unused

void lv_group_set_edge_cb(lv_group_t *group, lv_group_edge_cb_t edge_cb)

Set a function for a group which will be called when a focus edge is reached

Parameters
  • group -- pointer to a group

  • edge_cb -- the call back function or NULL if unused

void lv_group_set_refocus_policy(lv_group_t *group, lv_group_refocus_policy_t policy)

Set whether the next or previous item in a group is focused if the currently focused obj is deleted.

Parameters
  • group -- pointer to a group

  • policy -- new refocus policy enum

void lv_group_set_editing(lv_group_t *group, bool edit)

Manually set the current mode (edit or navigate).

Parameters
  • group -- pointer to group

  • edit -- true: edit mode; false: navigate mode

void lv_group_set_wrap(lv_group_t *group, bool en)

Set whether focus next/prev will allow wrapping from first->last or last->first object.

Parameters
  • group -- pointer to group

  • en -- true: wrapping enabled; false: wrapping disabled

struct _lv_obj_t *lv_group_get_focused(const lv_group_t *group)

Get the focused object or NULL if there isn't one

Parameters

group -- pointer to a group

Returns

pointer to the focused object

lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t *group)

Get the focus callback function of a group

Parameters

group -- pointer to a group

Returns

the call back function or NULL if not set

lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t *group)

Get the edge callback function of a group

Parameters

group -- pointer to a group

Returns

the call back function or NULL if not set

bool lv_group_get_editing(const lv_group_t *group)

Get the current mode (edit or navigate).

Parameters

group -- pointer to group

Returns

true: edit mode; false: navigate mode

bool lv_group_get_wrap(lv_group_t *group)

Get whether focus next/prev will allow wrapping from first->last or last->first object.

Parameters
  • group -- pointer to group

  • en -- true: wrapping enabled; false: wrapping disabled

uint32_t lv_group_get_obj_count(lv_group_t *group)

Get the number of object in the group

Parameters

group -- pointer to a group

Returns

number of objects in the group

struct _lv_group_t
#include <lv_group.h>

Groups can be used to logically hold objects so that they can be individually focused. They are NOT for laying out objects on a screen (try layouts for that).

Public Members

lv_ll_t obj_ll

Linked list to store the objects in the group

struct _lv_obj_t **obj_focus

The object in focus

lv_group_focus_cb_t focus_cb

A function to call when a new object is focused (optional)

lv_group_edge_cb_t edge_cb

A function to call when an edge is reached, no more focus targets are available in this direction (to allow edge feedback like a sound or a scroll bounce)

void *user_data
uint8_t frozen

1: can't focus to new object

uint8_t editing

1: Edit mode, 0: Navigate mode

uint8_t refocus_policy

1: Focus prev if focused on deletion. 0: Focus next if focused on deletion.

uint8_t wrap

1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end of list.