LVGL官方文档-7.11.0-5-Porting-Input device interface
Types of input devices
配置輸入設備的時候,需要初始化一個lv_indev_drv_t類型的變量:
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可以是如下值之一:
- LV_INDEV_TYPE_POINTER 觸摸板或者鼠標
- LV_INDEV_TYPE_KEYPAD 鍵盤或者按鍵板
- LV_INDEV_TYPE_ENCODER 能左、右、按下的編碼器
- LV_INDEV_TYPE_BUTTON 外部的能按屏幕的按鍵
read_cb是一個函數指針,這個函數會被周期性的調用來報告一個輸入設備的當前狀態。它也可以緩存數據。當緩存中沒有數據讀的時候,返回false,當緩存非空的時候,返回true。
請前往Input devices章節獲取更多關于輸入設備的信息。
Touchpad, mouse or any pointer
可以點擊屏幕上的點的設備屬于這一類。
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*/ }提示:這一類設備在“LV_INDEC_STATE_REL”狀態的時候,也要報告X/Y的坐標。
Keypad or keyboard
有完整字母的鍵盤,或者只有幾個導航按鍵的按鍵板輸入這一類。
要使用鍵盤或者按鍵板,需要做下面這些事情:
- 用LV_INDEV_TYPE_KEYPAD類型注冊read_cb。
- 在lv_conf.h中使能LV_USE_GROUP。
- 用lv_group_t *g = lv_group_create()創建對象組,然后用lv_group_add_obj(g, obj)向對象組中添加對象。
- 用lv_indev_set_group(my_indev, g)將創建的對象組賦值給輸入設備。其中,my_indev是lv_indev_drv_register()的返回值。
- 用LV_KEY_…在組內的對象之間導航。鍵值詳見lv_core/lv_group.h。
Encoder
用編碼器,你可以做以下4件事:
簡而言之,編碼器類輸入設備的工作方式如下:
- 通過轉編碼器,你可以在對象之間移動焦點。
- 在簡單對象(例如按鍵)上按編碼器,這個對象將會被點擊。
- 在復雜對象(例如列表,消息盒子等等)上按編碼器,對象會進入編輯模式,這個時候,轉編碼器能在這個復雜對象內部移動焦點。
- 長按按鍵,退出編輯模式。
與按鍵板類似,要使用編碼器,對象需要添加到對象組里。
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
除了標準的編碼器行為以外,你也可以利用其邏輯用按鍵來移動焦點,編輯控件。如果你只有幾個按鍵的時候,這會非常方便。或者可以同時使用按鍵和編碼器。
你需要有三個按鍵可用:
- LV_KEY_ENTER 模擬編碼器的按鈕
- LV_KEY_LEFT 模擬編碼器左轉
- LV_KEY_RIGHT 模擬編碼器右轉
- 其他按鍵將傳遞給有焦點的空間
如果按住按鍵不放,將會模擬周期性的編碼器點擊事件。周期由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
按鍵的意思是放在屏幕旁邊映射到屏幕固定坐標的實際按鍵。如果一個按鍵被按下了,就將模擬按在屏幕上映射的坐標處。(類似于觸摸板)
用lv_indev_set_button_points(my_indev, points_array)來映射按鍵到坐標。其中,points_array是這個樣子的:const lv_point_t points_array[] = {{10, 30}, {60. 90}, …}
需要注意的是,points_array需要是全局的,或者是函數里面的靜態變量。
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
除了read_cb之外,lv_indev_drv_t中還有一個feedback_cb回調可以用。feedback_cb在輸入設備發送任何類型的事件的時候都會被調用。(與設備類型無關)。這能實現給用戶的反饋,例如LV_EVENT_CLICK時間發生時,播放一個音效。
下面這些參數的默認值可以在lv_conf.h中設置,但是這些默認值在lv_indev_drv_t變量中可以被覆蓋。
- drag_limit 在實際拖動object之前,移動的像素數。
- drag_throw 拖動放開時的減速速度,單位是【%】。值越大,減速越快。
- long_press_time 按下多長時間發送LV_EVENT_LONG_PRESSED(單位毫秒)。
- long_press_rep_time 發送LV_EVENT_LONG_PRESSED_REPEAT的時間間隔。
- read_task 指向lv_task的指針,這個函數使用來讀取輸入設備的。他的參數可以用lv_task_…()函數來改變。
每個輸入設備都被分配到一個display。默認情況下,新的輸入設備被添加到最后創建或者最后選擇(用lv_disp_set_default())的display。分配到的display存儲在disp域,并且可以改變。
總結
以上是生活随笔為你收集整理的LVGL官方文档-7.11.0-5-Porting-Input device interface的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vimdiff 命令使用技巧
- 下一篇: 求圆面积 输出精度要求