feat(obj) Backport keypad and encoder scrolling from v7 lv_page to v8 lv_obj (#2390)
* support scrolling scrollable but non-editable objects thru keypad / encoder * update doc on `lv_obj` scrolling behavior by arrow keys
This commit is contained in:
@@ -166,7 +166,9 @@ By default, the objects can be clicked only on their coordinates, however, this
|
|||||||
Learn more about [Events](/overview/event).
|
Learn more about [Events](/overview/event).
|
||||||
|
|
||||||
## Keys
|
## Keys
|
||||||
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` make the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` make it unchecked.
|
If `LV_OBJ_FLAG_CHECKABLE` is enabled, `LV_KEY_RIGHT` and `LV_KEY_UP` make the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` make it unchecked.
|
||||||
|
|
||||||
|
If `LV_OBJ_FLAG_SCROLLABLE` is enabled, but the object is not editable (as declared by the widget class), the arrow keys (`LV_KEY_UP`, `LV_KEY_DOWN`, `LV_KEY_LEFT`, `LV_KEY_RIGHT`) scroll the object. If the object can only scroll vertically, `LV_KEY_LEFT` and `LV_KEY_RIGHT` will scroll up/down instead, making it compatible with an encoder input device. See [Input devices overview](/overview/indev) for more on encoder behaviors and the edit mode.
|
||||||
|
|
||||||
|
|
||||||
Learn more about [Keys](/overview/indev).
|
Learn more about [Keys](/overview/indev).
|
||||||
|
|||||||
@@ -251,13 +251,7 @@ lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
|||||||
{
|
{
|
||||||
lv_obj_t * act = lv_group_get_focused(group);
|
lv_obj_t * act = lv_group_get_focused(group);
|
||||||
if(act == NULL) return LV_RES_OK;
|
if(act == NULL) return LV_RES_OK;
|
||||||
|
return lv_event_send(act, LV_EVENT_KEY, &c);
|
||||||
lv_res_t res;
|
|
||||||
|
|
||||||
res = lv_event_send(act, LV_EVENT_KEY, &c);
|
|
||||||
if(res != LV_RES_OK) return res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
||||||
|
|||||||
@@ -554,9 +554,9 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
i->proc.pr_timestamp = lv_tick_get();
|
i->proc.pr_timestamp = lv_tick_get();
|
||||||
|
|
||||||
if(data->key == LV_KEY_ENTER) {
|
if(data->key == LV_KEY_ENTER) {
|
||||||
bool editable = lv_obj_is_editable(indev_obj_act);
|
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 == false) {
|
if(lv_group_get_editing(g) == true || editable_or_scrollable == false) {
|
||||||
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, indev_act);
|
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, indev_act);
|
||||||
if(indev_reset_check(&i->proc)) return;
|
if(indev_reset_check(&i->proc)) return;
|
||||||
}
|
}
|
||||||
@@ -590,12 +590,14 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
i->proc.longpr_rep_timestamp = lv_tick_get();
|
i->proc.longpr_rep_timestamp = lv_tick_get();
|
||||||
|
|
||||||
if(data->key == LV_KEY_ENTER) {
|
if(data->key == LV_KEY_ENTER) {
|
||||||
bool editable = lv_obj_is_editable(indev_obj_act);
|
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.*/
|
/*On enter long press toggle edit mode.*/
|
||||||
if(editable) {
|
if(editable_or_scrollable) {
|
||||||
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
|
/*Don't leave edit mode if there is only one object (nowhere to navigate)*/
|
||||||
if(lv_group_get_obj_count(g) > 1) {
|
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_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*/
|
lv_obj_clear_state(indev_obj_act, LV_STATE_PRESSED); /*Remove the pressed state manually*/
|
||||||
}
|
}
|
||||||
@@ -639,10 +641,11 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
LV_LOG_INFO("released");
|
LV_LOG_INFO("released");
|
||||||
|
|
||||||
if(data->key == LV_KEY_ENTER) {
|
if(data->key == LV_KEY_ENTER) {
|
||||||
bool editable = lv_obj_is_editable(indev_obj_act);
|
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*/
|
/*The button was released on a non-editable object. Just send enter*/
|
||||||
if(editable == false) {
|
if(editable_or_scrollable == false) {
|
||||||
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, indev_act);
|
lv_event_send(indev_obj_act, LV_EVENT_RELEASED, indev_act);
|
||||||
if(indev_reset_check(&i->proc)) return;
|
if(indev_reset_check(&i->proc)) return;
|
||||||
|
|
||||||
@@ -674,7 +677,8 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
}
|
}
|
||||||
/*If the focused object is editable and now in navigate mode then on enter switch edit
|
/*If the focused object is editable and now in navigate mode then on enter switch edit
|
||||||
mode*/
|
mode*/
|
||||||
else if(editable && !lv_group_get_editing(g) && !i->proc.long_pr_sent) {
|
else if(!i->proc.long_pr_sent) {
|
||||||
|
LV_LOG_INFO("entering edit mode");
|
||||||
lv_group_set_editing(g, true); /*Set edit mode*/
|
lv_group_set_editing(g, true); /*Set edit mode*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,9 +690,9 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
|
|
||||||
/*if encoder steps or simulated steps via left/right keys*/
|
/*if encoder steps or simulated steps via left/right keys*/
|
||||||
if(data->enc_diff != 0) {
|
if(data->enc_diff != 0) {
|
||||||
LV_LOG_INFO("rotated by %d", data->enc_diff);
|
|
||||||
/*In edit mode send LEFT/RIGHT keys*/
|
/*In edit mode send LEFT/RIGHT keys*/
|
||||||
if(lv_group_get_editing(g)) {
|
if(lv_group_get_editing(g)) {
|
||||||
|
LV_LOG_INFO("rotated by %+d (edit)", data->enc_diff);
|
||||||
int32_t s;
|
int32_t s;
|
||||||
if(data->enc_diff < 0) {
|
if(data->enc_diff < 0) {
|
||||||
for(s = 0; s < -data->enc_diff; s++) lv_group_send_data(g, LV_KEY_LEFT);
|
for(s = 0; s < -data->enc_diff; s++) lv_group_send_data(g, LV_KEY_LEFT);
|
||||||
@@ -699,6 +703,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
|||||||
}
|
}
|
||||||
/*In navigate mode focus on the next/prev objects*/
|
/*In navigate mode focus on the next/prev objects*/
|
||||||
else {
|
else {
|
||||||
|
LV_LOG_INFO("rotated by %+d (nav)", data->enc_diff);
|
||||||
int32_t s;
|
int32_t s;
|
||||||
if(data->enc_diff < 0) {
|
if(data->enc_diff < 0) {
|
||||||
for(s = 0; s < -data->enc_diff; s++) lv_group_focus_prev(g);
|
for(s = 0; s < -data->enc_diff; s++) lv_group_focus_prev(g);
|
||||||
|
|||||||
@@ -702,6 +702,34 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) && !lv_obj_is_editable(obj)) {
|
||||||
|
/*scroll by keypad or encoder*/
|
||||||
|
lv_anim_enable_t anim_enable = LV_ANIM_OFF;
|
||||||
|
lv_coord_t sl = lv_obj_get_scroll_left(obj);
|
||||||
|
lv_coord_t sr = lv_obj_get_scroll_right(obj);
|
||||||
|
char c = *((char *)lv_event_get_param(e));
|
||||||
|
if(c == LV_KEY_DOWN) {
|
||||||
|
/*use scroll_to_x/y functions to enforce scroll limits*/
|
||||||
|
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) + lv_obj_get_height(obj) / 4, anim_enable);
|
||||||
|
}
|
||||||
|
else if(c == LV_KEY_UP) {
|
||||||
|
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) - lv_obj_get_height(obj) / 4, anim_enable);
|
||||||
|
}
|
||||||
|
else if(c == LV_KEY_RIGHT) {
|
||||||
|
/*If the object can't be scrolled horizontally then scroll it vertically*/
|
||||||
|
if(!((lv_obj_get_scroll_dir(obj) & LV_DIR_HOR) && (sl > 0 || sr > 0)))
|
||||||
|
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) + lv_obj_get_height(obj) / 4, anim_enable);
|
||||||
|
else
|
||||||
|
lv_obj_scroll_to_x(obj, lv_obj_get_scroll_x(obj) + lv_obj_get_width(obj) / 4, anim_enable);
|
||||||
|
}
|
||||||
|
else if(c == LV_KEY_LEFT) {
|
||||||
|
/*If the object can't be scrolled horizontally then scroll it vertically*/
|
||||||
|
if(!((lv_obj_get_scroll_dir(obj) & LV_DIR_HOR) && (sl > 0 || sr > 0)))
|
||||||
|
lv_obj_scroll_to_y(obj, lv_obj_get_scroll_y(obj) - lv_obj_get_height(obj) / 4, anim_enable);
|
||||||
|
else
|
||||||
|
lv_obj_scroll_to_x(obj, lv_obj_get_scroll_x(obj) - lv_obj_get_width(obj) / 4, anim_enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(code == LV_EVENT_FOCUSED) {
|
else if(code == LV_EVENT_FOCUSED) {
|
||||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS)) {
|
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user