Input devices(输入设备)

查看原文

An input device usually means:

  • Pointer-like input device like touchpad or mouse

  • Keypads like a normal keyboard or simple numeric keypad

  • Encoders with left/right turn and push options

  • External hardware buttons which are assigned to specific points on the screen

一般来说输入设备可以是:

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

  • 像普通键盘或简单数字键盘那样的键盘

  • 带左/右转和推动选项的编码器

  • 分配给屏幕外围特定点的外部硬件按钮

查看原文

重要

Before reading further, please read the [Porting](/porting/indev) section of Input devices

重要

在进一步阅读之前,请阅读输入设备(Input devices)的 [Porting](/porting/indev) 部分

Pointers(光标)

查看原文

Pointer input devices (like a mouse) can have a cursor.

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

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

LV_IMG_DECLARE(mouse_cursor_icon);                          /*Declare the image file.*/
lv_obj_t * cursor_obj =  lv_img_create(lv_scr_act(), NULL); /*Create an image object for the cursor */
lv_img_set_src(cursor_obj, &mouse_cursor_icon);             /*Set the image source*/
lv_indev_set_cursor(mouse_indev, cursor_obj);               /*Connect the image  object to the driver*/
查看原文

Note that the cursor object should have lv_obj_set_click(cursor_obj, false). For images, clicking is disabled by default.

请注意,光标对象应该有 lv_obj_set_click(cursor_obj, false)

对于图像,默认情况下禁用 单击

Gestures (手势)

查看原文

Pointer input devives can detect basic gestures. By default, most of the widgets send the gestures to its parent, so finally the gestures can be detected on the screen object in a form of an LV_EVENT_GESTURE event. For example:

指针输入设备可以检测基本手势。默认情况下,大多数部件(对象)会将手势发送给其父级(事件冒泡),因此我们最终可以在屏幕对象 (lv_scr_act()) 上设置回调函数,在 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);
查看原文

To prevent passing the gesture event to the parent from an obejct use lv_obj_clear_flag(obj, LV_OBJ_FLAG_GESTURE_BUBBLE).

Note that, gestures are not triggered if an object is being scrolled.

如果不想让将手势事件从对象传递给父对象,请使用 lv_obj_clear_flag(obj, LV_OBJ_FLAG_GESTURE_BUBBLE); 禁用 事件冒泡

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

Keypad and encoder(键盘和编码器)

查看原文

You can fully control the user interface without touchpad or mouse using a keypad or encoder(s). It works similar to the TAB key on the PC to select the element in an application or a web page.

您可以使用键盘或编码器在没有触摸板或鼠标的情况下完全控制用户界面。它的工作原理类似于 PC 上的 TAB 键,用于选择应用程序或网页中的元素。

Groups(组)

查看原文

The objects, you want to control with keypad or encoder, needs to be added to a Group. In every group, there is exactly one focused object which receives the pressed keys or the encoder actions. For example, if a Text area is focused and you press some letter on a keyboard, the keys will be sent and inserted into the text area. Similarly, if a Slider is focused and you press the left or right arrows, the slider's value will be changed.

You need to associate an input device with a group. An input device can send the keys to only one group but, a group can receive data from more than one input device too.

To create a group use lv_group_t * g = lv_group_create() and to add an object to the group use lv_group_add_obj(g, obj).

To associate a group with an input device use lv_indev_set_group(indev, g), where indev is the return value of lv_indev_drv_register()

您想用键盘或编码器控制的对象需要将其添加到组(Groups),一般都会被添加进默认的 组(Groups)

在每一组中,同时只有一个焦点对象接收按下的键或编码器的动作。

例如,如果文本区域 被聚焦并且您在键盘上按下某个字母,则按键将被发送并插入到文本区域中。

类似地,如果 Slider 获得焦点并且您按下向左或向右箭头,则滑块的值将被更改。

将对象添加到 组(Groups) 还不够,我们还需要将输入设备与组关联。一个输入设备只能将按键发送给一组,但一组也可以从多个输入设备接收数据。

  • 要创建一个 组(Groups) 使用 lv_group_t * g = lv_group_create();

  • 将一个对象添加到 组(Groups) 中使用 lv_group_add_obj(g, obj);

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

Keys(按键)

查看原文

There are some predefined keys which have special meaning:

  • LV_KEY_NEXT Focus on the next object

  • LV_KEY_PREV Focus on the previous object

  • LV_KEY_ENTER Triggers LV_EVENT_PRESSED/CLICKED/LONG_PRESSED etc. events

  • LV_KEY_UP Increase value or move upwards

  • LV_KEY_DOWN Decrease value or move downwards

  • LV_KEY_RIGHT Increase value or move the the right

  • LV_KEY_LEFT Decrease value or move the the left

  • LV_KEY_ESC Close or exit (E.g. close a Drop down list)

  • LV_KEY_DEL Delete (E.g. a character on the right in a Text area)

  • LV_KEY_BACKSPACE Delete a character on the left (E.g. in a Text area)

  • LV_KEY_HOME Go to the beginning/top (E.g. in a Text area)

  • LV_KEY_END Go to the end (E.g. in a Text area))

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

  • 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 跳到最后(例如在 文本区域))

查看原文

The most important special keys are LV_KEY_NEXT/PREV, LV_KEY_ENTER and LV_KEY_UP/DOWN/LEFT/RIGHT. In your read_cb function, you should translate some of your keys to these special keys to navigate in the group and interact with the selected object.

Usually, it's enough to use only LV_KEY_LEFT/RIGHT because most of the objects can be fully controlled with them.

With an encoder, you should use only LV_KEY_LEFT, LV_KEY_RIGHT, and LV_KEY_ENTER.

最重要的特殊键是:

  • LV_KEY_NEXT/PREV

  • LV_KEY_ENTER

  • LV_KEY_UP/DOWN/LEFT/RIGHT

在您的 read_cb 函数中,应该优先考虑将一些键转换对应为这些特殊键,以便在组中导航并与所选对象进行交互。

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

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

Edit and navigate mode(编辑和导航模式)

查看原文

Since a keypad has plenty of keys, it's easy to navigate between the objects and edit them using the keypad. But the encoders have a limited number of "keys" and hence it is difficult to navigate using the default options. Navigate and Edit are created to avoid this problem with the encoders.

In Navigate mode, the encoders LV_KEY_LEFT/RIGHT is translated to LV_KEY_NEXT/PREV. Therefore the next or previous object will be selected by turning the encoder. Pressing LV_KEY_ENTER will change to Edit mode.

In Edit mode, LV_KEY_NEXT/PREV is usually used to edit the object. Depending on the object's type, a short or long press of LV_KEY_ENTER changes back to Navigate mode. Usually, an object which can not be pressed (like a Slider) leaves Edit mode on short click. But with objects where short click has meaning (e.g. Button), a long press is required.

由于小键盘有很多键,因此很容易在对象之间导航并使用小键盘对其进行编辑。但是编码器的“键”数量有限,因此很难使用默认选项进行导航。创建 NavigateEdit 是为了避免编码器出现此问题。

Navigate 模式下,编码器 LV_KEY_LEFT/RIGHT 被转换为 LV_KEY_NEXT/PREV。因此,将通过转动编码器来选择下一个或上一个对象。

LV_KEY_ENTER 将更改为 Edit 模式。 在Edit 模式下,LV_KEY_NEXT/PREV 通常用于编辑对象。 根据对象的类型,短按或长按 LV_KEY_ENTER 会变回 Navigate 模式。 通常,无法按下的对象(如 Slider)会在短按时离开 Edit 模式。但是对于短按有意义的对象(例如 Button),则需要长按。

Default group(默认组)

查看原文

Interactive widgets - such as buttons, checkboxes, sliders, etc - can be automatically added to a default group. Just create a group with lv_group_t * g = lv_group_create(); and set the default group with lv_group_set_default(g);

Don't forget to assign the input device(s) to the default group with lv_indev_set_group(my_indev, g);.

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

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

Styling(风格样式)

查看原文

If an object is focused either by clicking it via touchpad, or focused via an encoder or keypad it goes to LV_STATE_FOCUSED. Hence focused styles will be applied on it.

If the object goes to edit mode it goes to LV_STATE_FOCUSED | LV_STATE_EDITED state so these style properties will be shown.

For a more detaild description read the Style section.

如果通过触摸板单击对象或通过编码器或键盘聚焦对象,它会转到“LV_STATE_FOCUSED”。因此,将在其上应用重点样式。

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

有关更详细的说明,请阅读 样式 部分。

API

Input device(输入设备)

Functions

void lv_indev_read_timer_cb(lv_timer_t *timer)

Called periodically to read the input devices

参数

timer -- pointer to a timer to read

void lv_indev_enable(lv_indev_t *indev, bool en)
lv_indev_t *lv_indev_get_act(void)

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

返回

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

参数

indev -- pointer to an input device

返回

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

参数
  • 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

参数

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)

参数
  • 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)

参数
  • 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

参数
  • 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)

参数
  • 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

参数

indev -- pointer to an input device

返回

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)

参数

indev -- pointer to an input device

返回

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)

参数

indev -- pointer to an input device

返回

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)

参数

indev -- pointer to an input device

返回

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)

参数
  • 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

参数

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.

返回

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.

参数

indev -- pointer to an input device

返回

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

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

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

返回

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

Groups(组)

Typedefs

typedef uint8_t lv_key_t
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t*)
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

enum [anonymous]

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

返回

pointer to the new object group

void lv_group_del(lv_group_t *group)

Delete a group object

参数

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

参数

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

lv_group_t *lv_group_get_default(void)

Get the default group

返回

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

参数
  • 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

参数
  • 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

参数

obj -- pointer to an object to remove

void lv_group_remove_all_objs(lv_group_t *group)

Remove all objects from a group

参数

group -- pointer to a group

void lv_group_focus_obj(struct _lv_obj_t *obj)

Focus on an object (defocus the current)

参数

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)

参数

group -- pointer to a group

void lv_group_focus_prev(lv_group_t *group)

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

参数

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

参数
  • 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

参数
  • group -- pointer to a group

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

返回

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

参数
  • group -- pointer to a group

  • focus_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.

参数
  • 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).

参数
  • 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.

参数
  • 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

参数

group -- pointer to a group

返回

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

参数

group -- pointer to a group

返回

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).

参数

group -- pointer to group

返回

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.

参数
  • 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

参数

group -- pointer to a group

返回

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)

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.