GUI 输入设备补充说明

SDK 支持多种输入设备,其中以下几种输入设备,在 HoneyGUI 框架有相应的输入子系统支持:触摸板、键盘、滚轮。HoneyGUI 文档已对输入子系统以及移植说明有了一些介绍,可参考 GUI 输入子系统

本文对输入设备的移植、相关算法、输入设备的事件响应进行补充介绍。

触摸板

Module Touch

  • module_touch_common.c 中定义了 触摸板的一些通用行为,例如设备初始化、中断服务函数实现、获取数据接口实现等。

  • touch_xxxx.c 中定义了不同 touch driver 的读写实现。

  • 在调用过 touch_driver_init() 初始化 touch 设备后,touch 的信息首先会被中断响应到 TOUCH_INT_HANDLER

  • 中断服务函数需要调用 rtk_touch_hal_read_all() 收集 touch 原始数据,并填入 TOUCH_DATA 结构体。

    • 原始数据包括初次 touch 和当前 touch 坐标信息以及时间戳等。

    • TOUCH_DATA 信息是通过 get_raw_touch_data() 接口获取。

  • 同时,一个 OS timer 会启动,用于监控 touch 行为是否结束,Timeout 参数是通过 touch_set_timeout_ms() 设定的。

GUI 移植

  1. port_touchpad_get_data() :该函数会调用 get_raw_touch_data(),获取 TOUCH_DATA 并传递给 gui_touch_port_data_t

  2. gui_indev 结构体的初始化:主要是 port 接口的注册,和长按、短按、滑动、抬手等行为的时间设定。

  3. gui_port_indev_init() 中还要设定抬手时间( touch_timeout_ms ),时间需要和 module touch 的 OS timer timeout 一致。

GUI 触摸板算法

SDK 使用 tp_algo_v2.c 作为 GUI Touch 算法,该版本主要是解耦了 触摸板数据更新对于 GUI 服务器任务运行的依赖。 触摸板算法函数 tp_algo_process() 会在 GUI 服务器任务运行的较早时期调用,并在经过计算后,填入坐标信息、事件类型等数据到 touch_info_t 结构体。

GUI 触摸板事件响应

  • 结构体 touch_info_t 通常在控件的 draw prepare 过程中调用 tp_get_info() 获取,然后根据获取到的触摸信息上报不同的 event 给控件。

  • 随后调用 gui_obj_event_set() 设定当前控件在当前帧需要响应的事件。

  • GUI 上层应用需要通过 gui_obj_add_event_cb() 接口来绑定事件和回调函数。在控件 draw end 过程中,这些事件将会被收集并在所有控件的 draw end 过程完成后依次响应。

备注

  • gui_obj_add_event_cb() 接口通常会被 GUI 控件封装成具有具体行为意义的 API,推荐使用 GUI 控件的 API 完成事件和回调函数的绑定。

  • 一些控件例如窗帘、选项卡等控件,会实时响应 touch 行为,这些行为通常会在控件的 draw prepare 过程进行处理。

代码示例

在该示例中,创建一个 win 控件,通过 gui_win_long()win_benchmark_start_cb() 和长按行为进行绑定, 实现在 win 界面长按执行 app_benchmark_start()

static void prepare(gui_obj_t *obj)
{
   touch_info_t *tp = tp_get_info();
   gui_win_t *this = (void *)obj;
...
      case TOUCH_LONG:
            {
               if (this->long_flag == false)
               {
                  this->long_flag = true;
                  gui_obj_event_set(obj, GUI_EVENT_TOUCH_LONG);
               }
            }
            break;
...
}

static void win_benchmark_start_cb(void *obj, uint16_t event, void *param)
{
   switch (event)
   {
   case GUI_EVENT_TOUCH_LONG:
      {
            app_benchmark_start();
      }
      break;
...
   }
}
void design_tab_benchmark_main(void *parent)
{
...
   gui_win_t *win = gui_win_create(parent, "win_benchmark_main", 0, 0, 0, 0);
   gui_win_long(win, win_benchmark_start_cb, NULL);
...
}

键盘

Module Button

  • module_button.c 定义了 GPIO 按键的一些行为。包括初始化,中断服务函数,消抖处理等。

  • GPIO_BUTTON_HANDLER 中断服务函数需要调用 GPIOx_ReadInputDataBit 读取指定 GPIO 的输入极性,并开启一个 20ms 的 OS timer 用于消抖处理。

  • 消抖后,会将当前 GPIO 的输入极性、读取 id、时间戳等信息存入到 T_GPIO_KEY 结构体。

    • gpio_button_read_key() 接口用于获取 T_GPIO_KEY 结构体。

GUI 移植

  1. port_kb_get_data() :该函数将 T_GPIO_KEY 结构体进行简单处理后,传递给 kb_port_data 结构体。

  2. gui_indev 结构体的初始化:主要是 port 接口的注册,和长按、短按行为的时间设定。

GUI 键盘算法

SDK 使用 kb_algo.c 键盘算法,该算法和 tp_algo_v2.c 类似,算法函数 kb_algo_process() 会在 GUI 服务器任务运行的较早时期调用, 并在经过计算后将按键的状态信息、事件类型等数据存储到 kb_info_t 结构体中。

GUI 键盘事件响应

  • 结构体 kb_info_t 通常在控件的 draw prepare 过程,调用 kb_get_info() 获取,然后根据获取到的按键信息上报不同的 event 给控件。

  • 随后调用 gui_obj_event_set() 设定当前控件在当前帧需要响应的事件。

  • GUI 上层应用需要通过 gui_obj_add_event_cb() 接口来绑定事件和回调函数。在控件的 draw end 过程中,这些事件将会被收集并在所有控件的 draw end 过程完成后依次响应。

  • EVB 上的 KEY1 按键用于 LCD 唤醒功能,为了保证唤醒的实时性,采用在消抖函数直接发消息给 GUI task 的方式处理,唤醒 gui_wake_up_by_button()

滚轮

Module QDEC

  • module_qdec.c 定义了 QDEC 的一些行为,包括初始化,中断服务函数等。

  • QDEC_Handler 中断服务函数,通过调用 QDEC_GetAxisDirection 来获取 qdec 外设的数据,并存储到 T_QDEC_DATA 结构体中, qdec_read_data() 接口用于获取 T_QDEC_DATA 结构体的数据。

GUI 移植

  1. port_wheel_get_data():该函数将 T_GPIO_KEY 结构体进行简单处理后,传递给 wheel_port_data 结构体。

  2. gui_indev 结构体的初始化:主要是 port 接口的注册。

  3. port_wheel_reset_prev_count():用于息屏后一些计数的重置。

GUI 滚轮算法

SDK 使用 wheel_algo.c 滚轮算法,该算法和 tp_algo_v2.c 类似,算法函数 wheel_algo_process() 会在 GUI 服务器任务运行的较早时期被调用, 并在经过计算后把 滚轮移动步数、状态信息、事件类型等数据存储到 touch_info_t 结构体中。

GUI 滚轮事件响应

  • 结构体 touch_info_t 通常在控件的 draw prepare 过程调用 wheel_get_info() 获取,然后根据获取到的信息上报不同的 event 给控件。

  • 随后调用 gui_obj_event_set() 设定当前控件在当前帧需要响应的事件。

  • GUI 上层应用需要通过 gui_obj_add_event_cb() 接口来绑定事件和回调函数。在控件的 draw end 过程中,这些事件将会被收集并在所有控件的 draw end 过程完成后依次响应。

  • 目前 perspective 控件和 page 控件,支持 滚轮的一些简单操作。