diff --git a/src/lv_core/lv_flex.c b/src/lv_core/lv_flex.c index c75e66bc0..d28e3f143 100644 --- a/src/lv_core/lv_flex.c +++ b/src/lv_core/lv_flex.c @@ -73,6 +73,7 @@ void _lv_flex_refresh(lv_obj_t * cont) lv_coord_t abs_x = cont->coords.x1 + lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN) - lv_obj_get_scroll_left(cont); lv_coord_t abs_y = cont->coords.y1 + lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN) - lv_obj_get_scroll_top(cont); + lv_ll_t * ll = _lv_obj_get_child_ll(cont); lv_coord_t * cross_pos = (row ? &abs_y : &abs_x); lv_coord_t place = cont->flex_cont.place; @@ -92,7 +93,7 @@ void _lv_flex_refresh(lv_obj_t * cont) bool rev = cont->flex_cont.dir & LV_FLEX_REVERSE; if(place != LV_FLEX_START) { - track_first_item = rev ? _lv_ll_get_head(&cont->child_ll) : _lv_ll_get_tail(&cont->child_ll); + track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll); while(track_first_item) { /*Search the first item of the next row */ @@ -106,7 +107,7 @@ void _lv_flex_refresh(lv_obj_t * cont) place_content(place, max_cross_size, all_track_size,row_cnt, cross_pos, &gap); } - track_first_item = rev ? _lv_ll_get_head(&cont->child_ll) : _lv_ll_get_tail(&cont->child_ll); + track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll); while(track_first_item) { /*Search the first item of the next row */ next_track_first_item = find_track_end(cont, track_first_item, max_main_size, &grow_unit, &track_size); @@ -131,6 +132,8 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor void * (*ll_iter)(const lv_ll_t * , const void *) = dir & LV_FLEX_REVERSE ? _lv_ll_get_next : _lv_ll_get_prev; bool wrap = dir & LV_FLEX_WRAP ? true : false; + lv_ll_t * ll = _lv_obj_get_child_ll(cont); + lv_coord_t grow_sum = 0; lv_coord_t used_size = 0; lv_coord_t gap = cont->flex_cont.gap; @@ -143,7 +146,7 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor /*Ignore non-flex items*/ lv_coord_t main_set = (row ? item->x_set : item->y_set); if(LV_COORD_IS_FLEX(main_set) == false) { - item = ll_iter(&cont->child_ll, item); + item = ll_iter(ll, item); continue; } @@ -158,7 +161,7 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor } *track_cross_size = LV_MATH_MAX(get_cross_size(item), *track_cross_size); - item = ll_iter(&cont->child_ll, item); + item = ll_iter(ll, item); } if(used_size > 0) used_size -= gap; /*There is no gap after the last item*/ @@ -173,7 +176,7 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor /*Have at least one item in a row*/ if(item && item == item_start) { - item = ll_iter(&cont->child_ll, item); + item = ll_iter(ll, item); if(item) *track_cross_size = get_cross_size(item); } @@ -193,6 +196,7 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it lv_style_int_t (*get_margin_end)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom); void * (*ll_iter)(const lv_ll_t * , const void *) = dir & LV_FLEX_REVERSE ? _lv_ll_get_next : _lv_ll_get_prev; + lv_ll_t * ll = _lv_obj_get_child_ll(cont); lv_coord_t gap = cont->flex_cont.gap; lv_coord_t main_pos = 0; /*Reposition the children*/ @@ -202,7 +206,7 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it /*Ignore non-flex items*/ lv_coord_t main_set = (row ? item->x_set : item->y_set); if(LV_COORD_IS_FLEX(main_set) == false) { - item = ll_iter(&cont->child_ll, item); + item = ll_iter(ll, item); continue; } @@ -253,7 +257,7 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it _lv_obj_move_children_by(item, diff_x, diff_y); } main_pos += obj_get_main_size(item) + gap; - item = ll_iter(&cont->child_ll, item); + item = ll_iter(ll, item); } } diff --git a/src/lv_core/lv_grid.c b/src/lv_core/lv_grid.c index c4ed0a59b..dfbe1434e 100644 --- a/src/lv_core/lv_grid.c +++ b/src/lv_core/lv_grid.c @@ -81,7 +81,7 @@ void lv_obj_report_grid_change(const lv_grid_t * grid) while(d) { lv_obj_t * i; - _LV_LL_READ(d->scr_ll, i) { + _LV_LL_READ(&d->scr_ll, i) { report_grid_change_core(grid, i); } d = lv_disp_get_next(d); diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index 78fe73ea7..32f906dc5 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -92,7 +92,7 @@ void lv_group_del(lv_group_t * group) /*Remove the objects from the group*/ lv_obj_t ** obj; - _LV_LL_READ(group->obj_ll, obj) { + _LV_LL_READ(&group->obj_ll, obj) { (*obj)->group_p = NULL; } @@ -111,7 +111,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) if(group == NULL) return; /*Do not add the object twice*/ lv_obj_t ** obj_i; - _LV_LL_READ(group->obj_ll, obj_i) { + _LV_LL_READ(&group->obj_ll, obj_i) { if((*obj_i) == obj) { LV_LOG_INFO("lv_group_add_obj: the object is already added to this group"); return; @@ -173,7 +173,7 @@ void lv_group_remove_obj(lv_obj_t * obj) /*Search the object and remove it from its group */ lv_obj_t ** i; - _LV_LL_READ(g->obj_ll, i) { + _LV_LL_READ(&g->obj_ll, i) { if(*i == obj) { _lv_ll_remove(&g->obj_ll, i); lv_mem_free(i); @@ -198,7 +198,7 @@ void lv_group_remove_all_objs(lv_group_t * group) /*Remove the objects from the group*/ lv_obj_t ** obj; - _LV_LL_READ(group->obj_ll, obj) { + _LV_LL_READ(&group->obj_ll, obj) { (*obj)->group_p = NULL; } @@ -223,7 +223,7 @@ void lv_group_focus_obj(lv_obj_t * obj) lv_group_set_editing(g, false); lv_obj_t ** i; - _LV_LL_READ(g->obj_ll, i) { + _LV_LL_READ(&g->obj_ll, i) { if(*i == obj) { if(g->obj_focus != NULL) { (*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL); diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index e3d53935f..6be36ad7d 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -1048,7 +1048,8 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point) if(lv_obj_hit_test(obj, point)) { lv_obj_t * i; - _LV_LL_READ(obj->child_ll, i) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, i) { found_p = lv_indev_search_obj(i, point); /*If a child was found then break*/ diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 2fffbe30a..427618dfa 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -225,8 +225,10 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) else { LV_LOG_TRACE("Object create started"); LV_ASSERT_OBJ(parent, LV_OBJX_NAME); - - new_obj = _lv_ll_ins_head(&parent->child_ll); + if(parent->rare_attr == NULL) { + parent->rare_attr = lv_obj_allocate_rare_attr(parent); + } + new_obj = _lv_ll_ins_head(&parent->rare_attr->child_ll); LV_ASSERT_MEM(new_obj); if(new_obj == NULL) return NULL; @@ -260,9 +262,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) } - _lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t)); - - new_obj->ext_draw_pad = 0; #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL @@ -293,8 +292,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM; if(parent) new_obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE; new_obj->state = LV_STATE_DEFAULT; - new_obj->scroll.x = 0; - new_obj->scroll.y = 0; new_obj->ext_attr = NULL; @@ -562,6 +559,10 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent) lv_obj_invalidate(obj); + if(parent->rare_attr == NULL) { + parent->rare_attr = lv_obj_allocate_rare_attr(parent); + } + lv_obj_t * old_par = obj->parent; lv_point_t old_pos; old_pos.y = lv_obj_get_y(obj); @@ -575,7 +576,7 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent) old_pos.x = old_par->coords.x2 - obj->coords.x2; } - _lv_ll_chg_list(&obj->parent->child_ll, &parent->child_ll, obj, true); + _lv_ll_chg_list(_lv_obj_get_child_ll(obj->parent), _lv_obj_get_child_ll(parent), obj, true); obj->parent = parent; @@ -606,13 +607,14 @@ void lv_obj_move_foreground(lv_obj_t * obj) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_obj_t * parent = lv_obj_get_parent(obj); + lv_ll_t * ll = _lv_obj_get_child_ll(parent); /*Do nothing of already in the foreground*/ - if(_lv_ll_get_head(&parent->child_ll) == obj) return; + if(_lv_ll_get_head(ll) == obj) return; lv_obj_invalidate(parent); - _lv_ll_chg_list(&parent->child_ll, &parent->child_ll, obj, true); + _lv_ll_chg_list(ll, ll, obj, true); /*Notify the new parent about the child*/ parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj); @@ -629,13 +631,14 @@ void lv_obj_move_background(lv_obj_t * obj) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_obj_t * parent = lv_obj_get_parent(obj); + lv_ll_t * ll = _lv_obj_get_child_ll(parent); /*Do nothing of already in the background*/ - if(_lv_ll_get_tail(&parent->child_ll) == obj) return; + if(_lv_ll_get_tail(ll) == obj) return; lv_obj_invalidate(parent); - _lv_ll_chg_list(&parent->child_ll, &parent->child_ll, obj, false); + _lv_ll_chg_list(ll, ll, obj, false); /*Notify the new parent about the child*/ parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj); @@ -897,7 +900,8 @@ void lv_event_send_refresh_recursive(lv_obj_t * obj) if(res != LV_RES_OK) return; /*If invalid returned do not check the children*/ lv_obj_t * child; - _LV_LL_READ(obj->child_ll, child) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, child) { lv_event_send_refresh_recursive(child); } } @@ -1034,12 +1038,38 @@ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); void * new_ext = lv_mem_realloc(obj->ext_attr, ext_size); + LV_ASSERT_MEM(new_ext); if(new_ext == NULL) return NULL; obj->ext_attr = new_ext; return (void *)obj->ext_attr; } +/** + * Allocate a new ext. data for an object + * @param obj pointer to an object + * @param ext_size the size of the new ext. data + * @return pointer to the allocated ext. + * If out of memory NULL is returned and the original ext is preserved + */ +lv_obj_rare_attr_t * lv_obj_allocate_rare_attr(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + + if(obj->rare_attr == NULL) { + obj->rare_attr = lv_mem_realloc(obj->ext_attr, sizeof(lv_obj_rare_attr_t)); + LV_ASSERT_MEM(obj->rare_attr); + if(obj->rare_attr == NULL) return NULL; + + _lv_memset_00(obj->rare_attr, sizeof(lv_obj_rare_attr_t)); + _lv_ll_init(&(obj->rare_attr->child_ll), sizeof(lv_obj_t)); + + } + return obj->rare_attr; +} + + /*======================= * Getter functions @@ -1082,9 +1112,9 @@ lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj) scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/ lv_disp_t * d; - _LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d) { + _LV_LL_READ(&LV_GC_ROOT(_lv_disp_ll), d) { lv_obj_t * s; - _LV_LL_READ(d->scr_ll, s) { + _LV_LL_READ(&d->scr_ll, s) { if(s == scr) return d; } } @@ -1120,7 +1150,9 @@ lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return child ? _lv_ll_get_next(&obj->child_ll, child) : _lv_ll_get_head(&obj->child_ll); + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + if (child) return _lv_ll_get_next(ll, child); + else return _lv_ll_get_head(ll); } /** @@ -1134,7 +1166,9 @@ lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return child ? _lv_ll_get_prev(&obj->child_ll, child) : _lv_ll_get_tail(&obj->child_ll); + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + if(child) return _lv_ll_get_prev(ll, child); + else return _lv_ll_get_tail(ll); } /** @@ -1173,7 +1207,8 @@ uint32_t lv_obj_get_child_id(const lv_obj_t * obj) uint32_t id = 0; lv_obj_t * child; - _LV_LL_READ_BACK(obj->child_ll, child) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ_BACK(ll, child) { if(child == obj) return id; id++; } @@ -1192,7 +1227,8 @@ uint32_t lv_obj_count_children(const lv_obj_t * obj) lv_obj_t * i; uint16_t cnt = 0; - _LV_LL_READ(obj->child_ll, i) cnt++; + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, i) cnt++; return cnt; } @@ -1208,7 +1244,8 @@ uint32_t lv_obj_count_children_recursive(const lv_obj_t * obj) lv_obj_t * i; uint16_t cnt = 0; - _LV_LL_READ(obj->child_ll, i) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, i) { cnt++; /*Count the child*/ cnt += lv_obj_count_children_recursive(i); /*recursively count children's children*/ } @@ -1526,6 +1563,12 @@ bool lv_obj_is_instance_of(lv_obj_t * obj, const char * type_str) return false; } +lv_ll_t * _lv_obj_get_child_ll(const lv_obj_t * obj) +{ + if(obj->rare_attr) return &obj->rare_attr->child_ll; + else return NULL; +} + /*------------------- * OTHER FUNCTIONS *------------------*/ @@ -1599,7 +1642,7 @@ bool _lv_debug_check_obj_valid(const lv_obj_t * obj) lv_disp_t * disp = lv_disp_get_next(NULL); while(disp) { lv_obj_t * scr; - _LV_LL_READ(disp->scr_ll, scr) { + _LV_LL_READ(&disp->scr_ll, scr) { if(scr == obj) return true; bool found = obj_valid_child(scr, obj); @@ -1649,14 +1692,15 @@ static void obj_del_core(lv_obj_t * obj) #endif /*Recursively delete the children*/ + lv_ll_t * ll = _lv_obj_get_child_ll(obj); lv_obj_t * i; - i = _lv_ll_get_head(&(obj->child_ll)); + i = _lv_ll_get_head(ll); while(i != NULL) { /*Call the recursive delete to the child too*/ obj_del_core(i); /*Set i to the new head node*/ - i = _lv_ll_get_head(&(obj->child_ll)); + i = _lv_ll_get_head(ll); } lv_event_mark_deleted(obj); @@ -1690,7 +1734,7 @@ static void obj_del_core(lv_obj_t * obj) _lv_ll_remove(&d->scr_ll, obj); } else { - _lv_ll_remove(&(par->child_ll), obj); + _lv_ll_remove(_lv_obj_get_child_ll(par), obj); } /*Delete the base objects*/ @@ -1842,7 +1886,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area static void base_dir_refr_children(lv_obj_t * obj) { lv_obj_t * child; - _LV_LL_READ(obj->child_ll, child) { + _LV_LL_READ(_lv_obj_get_child_ll(obj), child) { if(child->base_dir == LV_BIDI_DIR_INHERIT) { lv_signal_send(child, LV_SIGNAL_BASE_DIR_CHG, NULL); base_dir_refr_children(child); @@ -1953,8 +1997,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) } if(w_new || h_new) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); lv_obj_t * child; - _LV_LL_READ(obj->child_ll, child) { + _LV_LL_READ(ll, child) { if((LV_COORD_IS_PCT(child->w_set) && w_new) || (LV_COORD_IS_PCT(child->h_set) && h_new)) { @@ -2006,8 +2051,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) /*Reposition non grid objects on by one*/ lv_obj_t * child; - _LV_LL_READ(obj->child_ll, child) { - if(!LV_COORD_IS_GRID(child->x_set) || !LV_COORD_IS_GRID(child->y_set)) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, child) { + if(LV_COORD_IS_PX(child->x_set) || LV_COORD_IS_PX(child->y_set)) { lv_obj_set_pos(child, child->x_set, child->y_set); } } @@ -2039,7 +2085,8 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin { /*Check all children of `parent`*/ lv_obj_t * child; - _LV_LL_READ(parent->child_ll, child) { + lv_ll_t * ll = _lv_obj_get_child_ll(parent); + _LV_LL_READ(ll, child) { if(child == obj_to_find) return true; /*Check the children*/ diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 5fdcc4f0a..5fcdb9ce0 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -208,12 +208,17 @@ typedef uint16_t lv_obj_flag_t; #include "lv_obj_draw.h" -struct _lv_obj_t { - struct _lv_obj_t * parent; /**< Pointer to the parent object*/ +typedef struct { lv_ll_t child_ll; /**< Linked list to store the children objects*/ + lv_point_t scroll; /**< The current X/Y scroll offset*/ +}lv_obj_rare_attr_t; + + +struct _lv_obj_t { + lv_obj_rare_attr_t * rare_attr; + struct _lv_obj_t * parent; /**< Pointer to the parent object*/ lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/ - lv_point_t scroll; /**< The current X/Y scroll offset*/ lv_event_cb_t event_cb; /**< Event callback function */ lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ @@ -548,6 +553,7 @@ void lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb); */ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size); +lv_obj_rare_attr_t * lv_obj_allocate_rare_attr(lv_obj_t * obj); /*======================= * Getter functions *======================*/ @@ -760,6 +766,8 @@ bool lv_obj_is_focused(const lv_obj_t * obj); */ bool lv_obj_is_instance_of(lv_obj_t * obj, const char * type_str); +lv_ll_t * _lv_obj_get_child_ll(const lv_obj_t * obj) ; + /** * Get the really focused object by taking `focus_parent` into account. * @param obj the start object diff --git a/src/lv_core/lv_obj_draw.c b/src/lv_core/lv_obj_draw.c index f01f26770..ac356a140 100644 --- a/src/lv_core/lv_obj_draw.c +++ b/src/lv_core/lv_obj_draw.c @@ -438,19 +438,23 @@ void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area) lv_coord_t obj_w = lv_obj_get_width(obj); bool ver_draw = false; - if((sm == LV_SCROLL_MODE_ON) || - (sm == LV_SCROLL_MODE_AUTO && (st > 0 || sb > 0)) || - (sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_VER)) { + if((obj->scroll_dir & LV_DIR_VER) && + ((sm == LV_SCROLL_MODE_ON) || + (sm == LV_SCROLL_MODE_AUTO && (st > 0 || sb > 0)) || + (sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_VER))) { ver_draw = true; } + bool hor_draw = false; - if((sm == LV_SCROLL_MODE_ON) || - (sm == LV_SCROLL_MODE_AUTO && (sl > 0 || sr > 0)) || - (sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_HOR)) { + if((obj->scroll_dir & LV_DIR_HOR) && + ((sm == LV_SCROLL_MODE_ON) || + (sm == LV_SCROLL_MODE_AUTO && (sl > 0 || sr > 0)) || + (sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_HOR))) { hor_draw = true; } + lv_coord_t ver_reg_space = ver_draw ? tickness + side_space : 0; lv_coord_t hor_req_space = hor_draw ? tickness + side_space : 0; lv_coord_t rem; diff --git a/src/lv_core/lv_obj_pos.c b/src/lv_core/lv_obj_pos.c index 125f65fe4..8aaabcdb1 100644 --- a/src/lv_core/lv_obj_pos.c +++ b/src/lv_core/lv_obj_pos.c @@ -694,7 +694,8 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff) { lv_obj_t * i; - _LV_LL_READ(obj->child_ll, i) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, i) { i->coords.x1 += x_diff; i->coords.y1 += y_diff; i->coords.x2 += x_diff; diff --git a/src/lv_core/lv_obj_scroll.c b/src/lv_core/lv_obj_scroll.c index c3b9a3976..a192ed4ad 100644 --- a/src/lv_core/lv_obj_scroll.c +++ b/src/lv_core/lv_obj_scroll.c @@ -73,8 +73,13 @@ lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj) */ void _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) { - obj->scroll.x += x; - obj->scroll.y += y; + if(x == 0 && y == 0) return; + + if(obj->rare_attr == NULL) { + obj->rare_attr = lv_obj_allocate_rare_attr(obj); + } + obj->rare_attr->scroll.x += x; + obj->rare_attr->scroll.y += y; _lv_obj_move_children_by(obj, x, y); lv_res_t res = lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL); @@ -107,7 +112,8 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN; if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX; lv_anim_set_time(&a, t); - lv_anim_set_values(&a, obj->scroll.x, obj->scroll.x + x); + lv_coord_t sl = lv_obj_get_scroll_left(obj); + lv_anim_set_values(&a, -sl, -sl + x); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_x_cb); lv_anim_set_path(&a, &path); lv_anim_start(&a); @@ -118,7 +124,8 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN; if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX; lv_anim_set_time(&a, t); - lv_anim_set_values(&a, obj->scroll.y, obj->scroll.y + y); + lv_coord_t st = lv_obj_get_scroll_top(obj); + lv_anim_set_values(&a, -st, -st + y); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t) scroll_anim_y_cb); lv_anim_set_path(&a, &path); lv_anim_start(&a); @@ -147,7 +154,7 @@ void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable */ void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en) { - lv_obj_scroll_by(obj, -x - obj->scroll.x, 0, anim_en); + lv_obj_scroll_by(obj, -x + lv_obj_get_scroll_left(obj), 0, anim_en); } /** @@ -157,7 +164,7 @@ void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en) */ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en) { - lv_obj_scroll_by(obj, 0, -y - obj->scroll.y, anim_en); + lv_obj_scroll_by(obj, 0, -y + lv_obj_get_scroll_top(obj), anim_en); } @@ -170,7 +177,8 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en) */ lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj) { - return -obj->scroll.y; + if(obj->rare_attr == NULL) return 0; + return -obj->rare_attr->scroll.y; } /** @@ -205,7 +213,7 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj) lv_coord_t self_h = _lv_obj_get_self_height(obj); self_h = self_h - (lv_obj_get_height(obj) - pad_top - pad_bottom); - self_h += obj->scroll.y; + self_h -= lv_obj_get_scroll_top(obj); return LV_MATH_MAX(child_res, self_h); } @@ -218,7 +226,8 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj) */ lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj) { - return -obj->scroll.x; + if(obj->rare_attr == NULL) return 0; + return -obj->rare_attr->scroll.x; } /** @@ -251,7 +260,7 @@ lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj) lv_coord_t self_w = _lv_obj_get_self_width(obj); self_w = self_w - (lv_obj_get_width(obj) - pad_right - pad_left); - self_w += obj->scroll.x; + self_w -= lv_obj_get_scroll_left(obj); return LV_MATH_MAX(child_res, self_w); } @@ -278,10 +287,10 @@ void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end) static void scroll_anim_x_cb(lv_obj_t * obj, lv_anim_value_t v) { - _lv_obj_scroll_by_raw(obj, v - obj->scroll.x, 0); + _lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_left(obj), 0); } static void scroll_anim_y_cb(lv_obj_t * obj, lv_anim_value_t v) { - _lv_obj_scroll_by_raw(obj, 0, v - obj->scroll.y); + _lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_top(obj)); } diff --git a/src/lv_core/lv_obj_style.c b/src/lv_core/lv_obj_style.c index fbd02c2f1..75e780843 100644 --- a/src/lv_core/lv_obj_style.c +++ b/src/lv_core/lv_obj_style.c @@ -191,7 +191,7 @@ void lv_obj_report_style_change(lv_style_t * style) while(d) { lv_obj_t * i; - _LV_LL_READ(d->scr_ll, i) { + _LV_LL_READ(&d->scr_ll, i) { report_style_change_core(style, i); } d = lv_disp_get_next(d); @@ -1247,7 +1247,7 @@ static void trans_anim_ready_cb(lv_anim_t * a) * It allows changing it by normal styles*/ bool running = false; lv_style_trans_t * tr_i; - _LV_LL_READ(LV_GC_ROOT(_lv_obj_style_trans_ll), tr_i) { + _LV_LL_READ(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr_i) { if(tr_i != tr && tr_i->obj == tr->obj && tr_i->part == tr->part && tr_i->prop == tr->prop) { running = true; } diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index d0ad96b52..ce8119808 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -582,7 +582,8 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) #endif lv_obj_t * i; - _LV_LL_READ(obj->child_ll, i) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ(ll, i) { found_p = lv_refr_get_top_obj(area_p, i); /*If a children is ok then break*/ @@ -626,13 +627,14 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p) /*Do until not reach the screen*/ while(par != NULL) { + lv_ll_t * ll = _lv_obj_get_child_ll(par); /*object before border_p has to be redrawn*/ - lv_obj_t * i = _lv_ll_get_prev(&(par->child_ll), border_p); + lv_obj_t * i = _lv_ll_get_prev(ll, border_p); while(i != NULL) { /*Refresh the objects*/ lv_refr_obj(i, mask_p); - i = _lv_ll_get_prev(&(par->child_ll), i); + i = _lv_ll_get_prev(ll, i); } /*Call the post draw design function of the parents of the to object*/ @@ -700,7 +702,8 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) lv_area_t mask_child; /*Mask from obj and its child*/ lv_obj_t * child_p; lv_area_t child_area; - _LV_LL_READ_BACK(obj->child_ll, child_p) { + lv_ll_t * ll = _lv_obj_get_child_ll(obj); + _LV_LL_READ_BACK(ll, child_p) { lv_obj_get_coords(child_p, &child_area); ext_size = child_p->ext_draw_pad; child_area.x1 -= ext_size; diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 895c064bb..e52a170b5 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -95,7 +95,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) lv_res_t res = LV_RES_INV; lv_img_decoder_t * d; - _LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) { + _LV_LL_READ(&LV_GC_ROOT(_lv_img_defoder_ll), d) { res = LV_RES_INV; if(d->info_cb) { res = d->info_cb(d, src, header); @@ -136,7 +136,7 @@ lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_co lv_res_t res = LV_RES_INV; lv_img_decoder_t * d; - _LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) { + _LV_LL_READ(&LV_GC_ROOT(_lv_img_defoder_ll), d) { /*Info an Open callbacks are required*/ if(d->info_cb == NULL || d->open_cb == NULL) continue; diff --git a/src/lv_hal/lv_hal_disp.c b/src/lv_hal/lv_hal_disp.c index 3e7a33c67..352047f59 100644 --- a/src/lv_hal/lv_hal_disp.c +++ b/src/lv_hal/lv_hal_disp.c @@ -188,7 +188,7 @@ void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv) memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t)); lv_obj_t * scr; - _LV_LL_READ(disp->scr_ll, scr) { + _LV_LL_READ(&disp->scr_ll, scr) { lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp)); } } diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index 4996eb8b1..f9b78fbe7 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -162,7 +162,7 @@ bool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb) lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb) { lv_anim_t * a; - _LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) { + _LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) { if(a->var == var && a->exec_cb == exec_cb) { return a; } @@ -179,7 +179,7 @@ uint16_t lv_anim_count_running(void) { uint16_t cnt = 0; lv_anim_t * a; - _LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++; + _LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) cnt++; return cnt; } @@ -444,7 +444,7 @@ static void anim_task(lv_task_t * param) (void)param; lv_anim_t * a; - _LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) { + _LV_LL_READ(&LV_GC_ROOT(_lv_anim_ll), a) { a->has_run = 0; } diff --git a/src/lv_misc/lv_fs.c b/src/lv_misc/lv_fs.c index 2a6a834bb..475fcab52 100644 --- a/src/lv_misc/lv_fs.c +++ b/src/lv_misc/lv_fs.c @@ -503,7 +503,7 @@ lv_fs_drv_t * lv_fs_get_drv(char letter) { lv_fs_drv_t * drv; - _LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) { + _LV_LL_READ(&LV_GC_ROOT(_lv_drv_ll), drv) { if(drv->letter == letter) { return drv; } @@ -521,7 +521,7 @@ char * lv_fs_get_letters(char * buf) lv_fs_drv_t * drv; uint8_t i = 0; - _LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv) { + _LV_LL_READ(&LV_GC_ROOT(_lv_drv_ll), drv) { buf[i] = drv->letter; i++; } diff --git a/src/lv_misc/lv_ll.c b/src/lv_misc/lv_ll.c index 4d3e4dabc..0b9d7df9b 100644 --- a/src/lv_misc/lv_ll.c +++ b/src/lv_misc/lv_ll.c @@ -156,6 +156,8 @@ void * _lv_ll_ins_tail(lv_ll_t * ll_p) */ void _lv_ll_remove(lv_ll_t * ll_p, void * node_p) { + if(ll_p == NULL) return; + if(_lv_ll_get_head(ll_p) == node_p) { /*The new head will be the node after 'n_act'*/ ll_p->head = _lv_ll_get_next(ll_p, node_p); @@ -249,7 +251,27 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h } } +/** + * Return with head node of the linked list + * @param ll_p pointer to linked list + * @return pointer to the head of 'll_p' + */ +void * _lv_ll_get_head(const lv_ll_t * ll_p) +{ + if(ll_p == NULL) return NULL; + return ll_p->head; +} +/** + * Return with tail node of the linked list + * @param ll_p pointer to linked list + * @return pointer to the head of 'll_p' + */ +void * _lv_ll_get_tail(const lv_ll_t * ll_p) +{ + if(ll_p == NULL) return NULL; + return ll_p->tail; +} /** * Return with the pointer of the next node after 'n_act' * @param ll_p pointer to linked list diff --git a/src/lv_misc/lv_ll.h b/src/lv_misc/lv_ll.h index 0fac6a713..812f840a6 100644 --- a/src/lv_misc/lv_ll.h +++ b/src/lv_misc/lv_ll.h @@ -98,20 +98,14 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h * @param ll_p pointer to linked list * @return pointer to the head of 'll_p' */ -static inline void * _lv_ll_get_head(const lv_ll_t * ll_p) -{ - return ll_p->head; -} +void * _lv_ll_get_head(const lv_ll_t * ll_p); /** * Return with tail node of the linked list * @param ll_p pointer to linked list * @return pointer to the head of 'll_p' */ -static inline void * _lv_ll_get_tail(const lv_ll_t * ll_p) -{ - return ll_p->tail; -} +void * _lv_ll_get_tail(const lv_ll_t * ll_p); /** * Return with the pointer of the next node after 'n_act' @@ -163,9 +157,9 @@ bool _lv_ll_is_empty(lv_ll_t * ll_p); * MACROS **********************/ -#define _LV_LL_READ(list, i) for(i = _lv_ll_get_head(&list); i != NULL; i = _lv_ll_get_next(&list, i)) +#define _LV_LL_READ(list, i) for((i) = _lv_ll_get_head(list); i != NULL; (i) = _lv_ll_get_next(list, i)) -#define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(&list); i != NULL; i = _lv_ll_get_prev(&list, i)) +#define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(list); i != NULL; i = _lv_ll_get_prev(list, i)) #ifdef __cplusplus } /* extern "C" */ diff --git a/src/lv_misc/lv_mem.c b/src/lv_misc/lv_mem.c index c41ea98eb..761440723 100644 --- a/src/lv_misc/lv_mem.c +++ b/src/lv_misc/lv_mem.c @@ -29,7 +29,7 @@ #endif #ifndef LV_MEM_FULL_DEFRAG_CNT - #define LV_MEM_FULL_DEFRAG_CNT 32 + #define LV_MEM_FULL_DEFRAG_CNT 64 #endif #ifdef LV_ARCH_64 diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index c051d9faa..c9b9837ae 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -305,7 +305,7 @@ void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio) /*Find the tasks with new priority*/ lv_task_t * i; - _LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i) { + _LV_LL_READ(&LV_GC_ROOT(_lv_task_ll), i) { if(i->prio <= prio) { if(i != task) _lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, i); break; diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 31ad91d04..f8652378b 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -203,6 +203,7 @@ static bool inited; static void basic_init(void) { + style_init_reset(&styles->sb); lv_style_set_scrollbar_bg_opa(&styles->sb, LV_STATE_DEFAULT, LV_OPA_COVER); lv_style_set_scrollbar_bg_color(&styles->sb, LV_STATE_DEFAULT, (IS_LIGHT ? lv_color_hex(0xcccfd1) : lv_color_hex(0x777f85))); lv_style_set_scrollbar_radius(&styles->sb, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);