Skip to content

Commit

Permalink
fix(obj): readjust scroll after layout when child removed (lvgl#4916)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasf committed Dec 4, 2023
1 parent 85776ae commit 2a03118
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 19 deletions.
4 changes: 4 additions & 0 deletions src/core/lv_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,10 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
lv_obj_mark_layout_as_dirty(obj);
}
}
else if(code == LV_EVENT_CHILD_DELETED) {
obj->readjust_scroll_after_layout = 1;
lv_obj_mark_layout_as_dirty(obj);
}
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
lv_coord_t d = lv_obj_calculate_ext_draw_size(obj, LV_PART_MAIN);
lv_event_set_ext_draw_size(e, d);
Expand Down
1 change: 1 addition & 0 deletions src/core/lv_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ typedef struct _lv_obj_t {
lv_obj_flag_t flags;
lv_state_t state;
uint16_t layout_inv : 1;
uint16_t readjust_scroll_after_layout : 1;
uint16_t scr_layout_inv : 1;
uint16_t skip_trans : 1;
uint16_t style_cnt : 6;
Expand Down
28 changes: 16 additions & 12 deletions src/core/lv_obj_pos.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ bool lv_obj_refr_size(lv_obj_t * obj)
/*Invalidate the new area*/
lv_obj_invalidate(obj);

lv_obj_readjust_scroll(obj, LV_ANIM_OFF);
obj->readjust_scroll_after_layout = 1;

/*If the object was out of the parent invalidate the new scrollbar area too.
*If it wasn't out of the parent but out now, also invalidate the scrollbars*/
Expand Down Expand Up @@ -1137,20 +1137,24 @@ static void layout_update_core(lv_obj_t * obj)
layout_update_core(child);
}

if(obj->layout_inv == 0) return;
if(obj->layout_inv) {
obj->layout_inv = 0;
lv_obj_refr_size(obj);
lv_obj_refr_pos(obj);

obj->layout_inv = 0;

lv_obj_refr_size(obj);
lv_obj_refr_pos(obj);

if(child_cnt > 0) {
uint32_t layout_id = lv_obj_get_style_layout(obj, LV_PART_MAIN);
if(layout_id > 0 && layout_id <= layout_cnt) {
void * user_data = LV_GC_ROOT(_lv_layout_list)[layout_id - 1].user_data;
LV_GC_ROOT(_lv_layout_list)[layout_id - 1].cb(obj, user_data);
if(child_cnt > 0) {
uint32_t layout_id = lv_obj_get_style_layout(obj, LV_PART_MAIN);
if(layout_id > 0 && layout_id <= layout_cnt) {
void * user_data = LV_GC_ROOT(_lv_layout_list)[layout_id - 1].user_data;
LV_GC_ROOT(_lv_layout_list)[layout_id - 1].cb(obj, user_data);
}
}
}

if(obj->readjust_scroll_after_layout) {
obj->readjust_scroll_after_layout = 0;
lv_obj_readjust_scroll(obj, LV_ANIM_OFF);
}
}

static void transform_point(const lv_obj_t * obj, lv_point_t * p, bool inv)
Expand Down
2 changes: 1 addition & 1 deletion src/core/lv_obj_scroll.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ void lv_obj_get_scrollbar_area(struct _lv_obj_t * obj, lv_area_t * hor, lv_area_
void lv_obj_scrollbar_invalidate(struct _lv_obj_t * obj);

/**
* Checked if the content is scrolled "in" and adjusts it to a normal position.
* Checks if the content is scrolled "in" and adjusts it to a normal position.
* @param obj pointer to an object
* @param anim_en LV_ANIM_ON/OFF
*/
Expand Down
6 changes: 0 additions & 6 deletions src/core/lv_obj_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ void lv_obj_del(lv_obj_t * obj)
lv_obj_invalidate(obj);

lv_obj_t * par = lv_obj_get_parent(obj);
if(par) {
lv_obj_scrollbar_invalidate(par);
}

lv_disp_t * disp = NULL;
bool act_scr_del = false;
Expand All @@ -65,8 +62,6 @@ void lv_obj_del(lv_obj_t * obj)

/*Call the ancestor's event handler to the parent to notify it about the child delete*/
if(par) {
lv_obj_update_layout(par);
lv_obj_readjust_scroll(par, LV_ANIM_OFF);
lv_obj_scrollbar_invalidate(par);
lv_event_send(par, LV_EVENT_CHILD_CHANGED, NULL);
lv_event_send(par, LV_EVENT_CHILD_DELETED, NULL);
Expand Down Expand Up @@ -173,7 +168,6 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
obj->parent = parent;

/*Notify the original parent because one of its children is lost*/
lv_obj_readjust_scroll(old_parent, LV_ANIM_OFF);
lv_obj_scrollbar_invalidate(old_parent);
lv_event_send(old_parent, LV_EVENT_CHILD_CHANGED, obj);
lv_event_send(old_parent, LV_EVENT_CHILD_DELETED, NULL);
Expand Down

0 comments on commit 2a03118

Please sign in to comment.