/**
* 处理来自LV_INDEV_TYPE_ENCODER输入设备的新点
* @param i 指向输入设备的指针
* @param data 指向从输入设备读取的数据的指针
*/
static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
{
// 如果当前状态为按下且等待释放标志被设置,则直接返回,不处理
if(data->state == LV_INDEV_STATE_PRESSED && i->proc.wait_until_release) return;
// 如果设置了等待释放标志,则重置相关处理状态
if(i->proc.wait_until_release)
{
i->proc.wait_until_release = 0;// 重置等待释放标志
i->proc.pr_timestamp = 0;// 重置按下时间戳
i->proc.long_pr_sent = 0;// 重置长按发送标志
i->proc.types.keypad.last_state = LV_INDEV_STATE_RELEASED; /*To skip the processing of release*/// 设置上一状态为释放,跳过释放处理
}
/*Save the last keys before anything else.
*They need to be already saved if the function returns for any reason*/
// 在任何其他处理之前保存最后的按键状态。如果函数因任何原因返回,它们需要已经被保存
lv_indev_state_t last_state = i->proc.types.keypad.last_state;// 保存上一个状态
i->proc.types.keypad.last_state = data->state;// 更新当前状态
i->proc.types.keypad.last_key = data->key;// 更新按键值
lv_group_t * g = i->group;// 获取输入设备关联的组
if(g == NULL) return;// 如果没有关联组,则直接返回
indev_obj_act = lv_group_get_focused(g);// 获取当前焦点对象
if(indev_obj_act == NULL) return;// 如果没有焦点对象,则直接返回
/*Process the steps they are valid only with released button*/
// 仅当按钮释放时才处理步进值
if(data->state != LV_INDEV_STATE_RELEASED)
{
data->enc_diff = 0;// 如果状态不是释放,则步进差值置为0
}
/*Refresh the focused object. It might change due to lv_group_focus_prev/next*/
// 刷新焦点对象。由于可能通过lv_group_focus_prev/next更改,需要重新获取
indev_obj_act = lv_group_get_focused(g);
if(indev_obj_act == NULL) return;
/*Button press happened*/
// 按钮按下事件处理
if(data->state == LV_INDEV_STATE_PRESSED && last_state == LV_INDEV_STATE_RELEASED)
{
LV_LOG_INFO("pressed");// 记录按下信息
i->proc.pr_timestamp = lv_tick_get();// 记录按下时间戳
// 根据按键类型分别处理
if(data->key == LV_KEY_ENTER)
{
bool editable_or_scrollable = lv_obj_is_editable(indev_obj_act) ||
lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_SCROLLABLE);
// 如果对象处于编辑模式或不可滚动,则发送按下事件
if(lv_group_get_editing(g) == true || editable_or_scrollable == false)
{
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, indev_act);
if(indev_reset_check(&i->proc)) return;
}
}
else if(data->key == LV_KEY_LEFT)
{
/*emulate encoder left*/
// 模拟编码器左旋
data->enc_diff--;
}
else if(data->key == LV_KEY_RIGHT)
{
/*emulate encoder right*/
// 模拟编码器右旋
data->enc_diff++;
}
else if(data->key == LV_KEY_ESC)
{
/*Send the ESC as a normal KEY*/
// 将ESC作为普通按键发送
lv_group_send_data(g, LV_KEY_ESC);
if(indev_reset_check(&i->proc)) return;
lv_event_send(indev_obj_act, LV_EVENT_CANCEL, indev_act);
if(indev_reset_check(&i->proc)) return;
}
/*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/
// 将其他按键直接发送给对象(例如'A'或`LV_GROUP_KEY_RIGHT`)
else
{
lv_group_send_data(g, data->key);
if(indev_reset_check(&i->proc)) return;
}
}
/*Pressing*/
// 持续按压处理
else if(data->state == LV_INDEV_STATE_PRESSED && last_state == LV_INDEV_STATE_PRESSED)
{
/*Long press*/
// 长按处理
uint32_t time1 = lv_tick_elaps(i->proc.pr_timestamp);
uint32_t time2 = i->driver->long_press_time;
uint32_t time12 = (time1 > time2) ? 1:0;
uint32_t time3 = lv_tick_elaps(i->proc.longpr_rep_timestamp);
uint32_t time4 = i->driver->long_press_repeat_time;
uint32_t time34 = (time3 > time4) ? 1:0;
if(i->proc.long_pr_sent == 0 && time12)
{
i->proc.long_pr_sent = 1;
i->proc.longpr_rep_timestamp = lv_tick_get();
// 长按ENTER键的特殊处理
if(data->key == LV_KEY_ENTER)
{
bool editable_or_scrollable = lv_obj_is_editable(indev_obj_act) ||
lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_SCROLLABLE);
/*On enter long press toggle edit mode.*/
// 在可编辑或可滚动对象上长按ENTER键切换编辑模式
if(editable_or_scrollable)
{
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
// 如果组中只有一个对象,则不退出编辑模式(无处导航)
if(lv_group_get_obj_count(g) > 1)
{
LV_LOG_INFO("toggling edit mode");
lv_group_set_editing(g, lv_group_get_editing(g) ? false : true); /*Toggle edit mode on long press*/// 切换编辑模式
lv_obj_clear_state(indev_obj_act, LV_STATE_PRESSED); /*Remove the pressed state manually*/// 手动移除按压状态
}
}
/*If not editable then just send a long press Call the ancestor's event handler*/
// 如果对象不可编辑,则仅发送长按事件
else
{
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, indev_act);
if(indev_reset_check(&i->proc)) return;
}
}
i->proc.long_pr_sent = 1;
}
/*Long press repeated time has elapsed?*/
// 长按重复时间已到?
else if(i->proc.long_pr_sent != 0 && time34)
{
i->proc.longpr_rep_timestamp = lv_tick_get();
// 根据按键类型进行长按重复事件的处理
if(data->key == LV_KEY_ENTER)
{
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, indev_act);
if(indev_reset_check(&i->proc)) return;
}
else if(data->key == LV_KEY_LEFT)
{
/*emulate encoder left*/
// 模拟编码器左旋
data->enc_diff--;
}
else if(data->key == LV_KEY_RIGHT)
{
/*emulate encoder right*/
// 模拟编码器右旋
data->enc_diff++;
}
else
{
// 将其他按键直接发送给对象
lv_group_send_data(g, data->key);
if(indev_reset_check(&i->proc)) return;
}
}
}
/*Release happened*/
// 释放事件处理
else if(data->state == LV_INDEV_STATE_RELEASED && last_state == LV_INDEV_STATE_PRESSED)
{
LV_LOG_INFO("released"); // 记录释放信息
// 释放ENTER键的特殊处理
if(data->key == LV_KEY_ENTER)
{
bool editable_or_scrollable = lv_obj_is_editable(indev_obj_act) ||
lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_SCROLLABLE);
/*The button was released on a non-editable object. Just send enter*/
// 在非可编辑对象上释放按钮。仅发送enter
if(editable_or_scrollable == false)
{
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, indev_act);
if(indev_reset_check(&i->proc)) return;
if(i->proc.long_pr_sent == 0) lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, indev_act);
if(indev_reset_check(&i->proc)) return;
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, indev_act);
if(indev_reset_check(&i->proc)) return;
}
/*An object is being edited and the button is released.*/
// 正在编辑的对象上释放按钮
else if(lv_group_get_editing(g))
{
/*Ignore long pressed enter release because it comes from mode switch*/
// 忽略来自模式切换的长按释放
if(!i->proc.long_pr_sent || lv_group_get_obj_count(g) <= 1)
{
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, indev_act);
if(indev_reset_check(&i->proc)) return;
lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, indev_act);
if(indev_reset_check(&i->proc)) return;
lv_event_send(indev_obj_act, LV_EVENT_CLICKED, indev_act);
if(indev_reset_check(&i->proc)) return;
lv_group_send_data(g, LV_KEY_ENTER);
if(indev_reset_check(&i->proc)) return;
}
else
{
lv_obj_clear_state(indev_obj_act, LV_STATE_PRESSED); /*Remove the pressed state manually*/ // 手动移除按压状态
}
}
/*If the focused object is editable and now in navigate mode then on enter switch edit
mode*/
// 如果焦点对象可编辑且当前处于导航模式,则在ENTER释放时切换到编辑模式
else if(!i->proc.long_pr_sent)
{
LV_LOG_INFO("entering edit mode");
lv_group_set_editing(g, true); /*Set edit mode*/ // 设置编辑模式
}
}
i->proc.pr_timestamp = 0;// 重置按下时间戳
i->proc.long_pr_sent = 0;// 重置长按发送标志
}
indev_obj_act = NULL;// 重置当前活动对象指针
/*if encoder steps or simulated steps via left/right keys*/
// 如果有编码器步进或通过左/右键模拟的步进
if(data->enc_diff != 0)
{
/*In edit mode send LEFT/RIGHT keys*/
// 在编辑模式下发送左/右键
if(lv_group_get_editing(g))
{
LV_LOG_INFO("rotated by %+d (edit)", data->enc_diff);// 记录编辑模式下的旋转信息
int32_t s;
if(data->enc_diff < 0)
{
for(s = 0; s < -data->enc_diff; s++)
{
lv_group_send_data(g, LV_KEY_LEFT);// 发送左键
if(indev_reset_check(&i->proc)) return;
}
}
else if(data->enc_diff > 0)
{
for(s = 0; s < data->enc_diff; s++)
{
lv_group_send_data(g, LV_KEY_RIGHT);// 发送右键
if(indev_reset_check(&i->proc)) return;
}
}
}
/*In navigate mode focus on the next/prev objects*/// 在导航模式下聚焦下一个/上一个对象
else
{
LV_LOG_INFO("rotated by %+d (nav)", data->enc_diff); // 记录导航模式下的旋转信息
int32_t s;
if(data->enc_diff < 0)
{
for(s = 0; s < -data->enc_diff; s++)
{
lv_group_focus_prev(g);// 聚焦上一个对象
if(indev_reset_check(&i->proc)) return;
}
}
else if(data->enc_diff > 0)
{
for(s = 0; s < data->enc_diff; s++)
{
lv_group_focus_next(g);// 聚焦下一个对象
if(indev_reset_check(&i->proc)) return;
}
}
}
}
}