Merge pull request #1522 from fhorinek/encoder-buttons

Encoder input proc support for buttons
This commit is contained in:
Gabor Kiss-Vamosi
2020-06-08 14:14:32 +02:00
committed by GitHub
3 changed files with 164 additions and 92 deletions

View File

@@ -607,28 +607,9 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
indev_obj_act = lv_group_get_focused(g);
if(indev_obj_act == NULL) return;
/*Process the steps first. They are valid only with released button*/
if(data->state == LV_INDEV_STATE_REL) {
/*In edit mode send LEFT/RIGHT keys*/
if(lv_group_get_editing(g)) {
int32_t s;
if(data->enc_diff < 0) {
for(s = 0; s < -data->enc_diff; s++) lv_group_send_data(g, LV_KEY_LEFT);
}
else if(data->enc_diff > 0) {
for(s = 0; s < data->enc_diff; s++) lv_group_send_data(g, LV_KEY_RIGHT);
}
}
/*In navigate mode focus on the next/prev objects*/
else {
int32_t s;
if(data->enc_diff < 0) {
for(s = 0; s < -data->enc_diff; s++) lv_group_focus_prev(g);
}
else if(data->enc_diff > 0) {
for(s = 0; s < data->enc_diff; s++) lv_group_focus_next(g);
}
}
/*Process the steps they are valid only with released button*/
if(data->state != LV_INDEV_STATE_REL) {
data->enc_diff = 0;
}
/*Refresh the focused object. It might change due to lv_group_focus_prev/next*/
@@ -637,10 +618,13 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
/*Button press happened*/
if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) {
i->proc.pr_timestamp = lv_tick_get();
if (data->key == LV_KEY_ENTER) {
bool editable = false;
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
i->proc.pr_timestamp = lv_tick_get();
if(lv_group_get_editing(g) == true || editable == false) {
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, NULL);
if(indev_reset_check(&i->proc)) return;
@@ -648,10 +632,33 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
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*/
lv_group_send_data(g, LV_KEY_ESC);
lv_event_send(indev_obj_act, LV_EVENT_CANCEL, NULL);
if(indev_reset_check(&i->proc)) return;
}
/*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/
else {
lv_group_send_data(g, data->key);
}
}
/*Pressing*/
else if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_PR) {
/* Long press*/
if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
i->proc.long_pr_sent = 1;
i->proc.longpr_rep_timestamp = lv_tick_get();
if (data->key == LV_KEY_ENTER) {
bool editable = false;
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
@@ -669,12 +676,39 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);
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 && lv_tick_elaps(i->proc.longpr_rep_timestamp) > i->driver.long_press_rep_time) {
i->proc.longpr_rep_timestamp = lv_tick_get();
if(data->key == LV_KEY_ENTER) {
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, NULL);
if(indev_reset_check(&i->proc)) return;
lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
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_REL && last_state == LV_INDEV_STATE_PR) {
if (data->key == LV_KEY_ENTER) {
bool editable = false;
indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);
@@ -716,11 +750,37 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
else if(editable && !g->editing && !i->proc.long_pr_sent) {
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)) {
int32_t s;
if(data->enc_diff < 0) {
for(s = 0; s < -data->enc_diff; s++) lv_group_send_data(g, LV_KEY_LEFT);
}
else if(data->enc_diff > 0) {
for(s = 0; s < data->enc_diff; s++) lv_group_send_data(g, LV_KEY_RIGHT);
}
}
/*In navigate mode focus on the next/prev objects*/
else {
int32_t s;
if(data->enc_diff < 0) {
for(s = 0; s < -data->enc_diff; s++) lv_group_focus_prev(g);
}
else if(data->enc_diff > 0) {
for(s = 0; s < data->enc_diff; s++) lv_group_focus_next(g);
}
}
}
#else
(void)data; /*Unused*/
(void)i; /*Unused*/

View File

@@ -143,6 +143,11 @@ bool _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
else if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) {
data->key = indev->proc.types.keypad.last_key;
}
/*For compatibility assume that used button was enter (encoder push) */
else if(indev->driver.type == LV_INDEV_TYPE_ENCODER) {
data->key = LV_KEY_ENTER;
data->enc_diff = 0;
}
if(indev->driver.read_cb) {
LV_LOG_TRACE("idnev read started");

View File

@@ -712,6 +712,11 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
if(ext->last_sel_btn) lv_list_focus_btn(list, ext->last_sel_btn);
else lv_list_focus_btn(list, lv_list_get_next_btn(list, NULL));
}
if(indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(g) == false) {
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
if(ext->act_sel_btn) lv_obj_clear_state(ext->act_sel_btn, LV_STATE_PRESSED);
if(ext->last_sel_btn) lv_obj_clear_state(ext->last_sel_btn, LV_STATE_PRESSED);
}
#endif
}
else if(sign == LV_SIGNAL_DEFOCUS) {
@@ -811,8 +816,10 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
else if(sign == LV_SIGNAL_CLEANUP) {
#if LV_USE_GROUP
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
lv_obj_t * sel = lv_list_get_btn_selected(list);
if(sel == btn) lv_list_focus_btn(list, lv_list_get_next_btn(list, btn));
if(ext->last_sel_btn == btn) ext->last_sel_btn = NULL;
#endif
}