diff --git a/src/lv_core/lv_flex.c b/src/lv_core/lv_flex.c index d28e3f143..bf803179f 100644 --- a/src/lv_core/lv_flex.c +++ b/src/lv_core/lv_flex.c @@ -38,20 +38,25 @@ static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t trac void lv_obj_set_flex_cont(lv_obj_t * obj, lv_flex_dir_t flex_dir, lv_flex_place_t flex_place) { - if(obj->flex_cont.dir == flex_dir && obj->flex_cont.place == flex_place) return; + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); - obj->flex_cont.dir = flex_dir; - obj->flex_cont.place = flex_place; + if(obj->spec_attr->flex_cont.dir == flex_dir && obj->spec_attr->flex_cont.place == flex_place) return; + + obj->spec_attr->flex_cont.dir = flex_dir & 0x3; + obj->spec_attr->flex_cont.wrap = flex_dir & LV_FLEX_WRAP ? 1 : 0; + obj->spec_attr->flex_cont.rev = flex_dir & LV_FLEX_REVERSE ? 1 : 0; + obj->spec_attr->flex_cont.place = flex_place; _lv_flex_refresh(obj); } void lv_obj_set_flex_gap(lv_obj_t * obj, lv_coord_t gap) { + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); - if(obj->flex_cont.gap == gap) return; + if(obj->spec_attr->flex_cont.gap == gap) return; - obj->flex_cont.gap = gap; + obj->spec_attr->flex_cont.gap = gap; _lv_flex_refresh(obj); } @@ -62,21 +67,52 @@ void lv_obj_set_flex_item(lv_obj_t * obj, lv_flex_place_t place) lv_obj_set_pos(obj, f, f); } +lv_flex_dir_t lv_obj_get_flex_dir(const lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->flex_cont.dir; + else return LV_FLEX_DIR_NONE; +} + +lv_flex_place_t lv_obj_get_flex_place(const lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->flex_cont.place; + else return LV_FLEX_START; +} + +bool lv_obj_get_flex_wrap(const lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->flex_cont.wrap; + else return false; +} + +bool lv_obj_get_flex_reverse(const lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->flex_cont.rev; + else return false; +} + +lv_coord_t lv_obj_get_flex_gap(const lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->flex_cont.gap; + else return 0; +} + void _lv_flex_refresh(lv_obj_t * cont) { - if(cont->flex_cont.dir == LV_FLEX_DIR_NONE) return; + lv_flex_dir_t dir = lv_obj_get_flex_dir(cont); + + if(dir == LV_FLEX_DIR_NONE) return; - lv_flex_dir_t dir = cont->flex_cont.dir & 0x3; bool row = dir == LV_FLEX_DIR_ROW ? true : false; /*Count the grow units and free space*/ lv_coord_t max_main_size = (row ? lv_obj_get_width_fit(cont) : lv_obj_get_height_fit(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_coord_t place = lv_obj_get_flex_place(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; if((row && cont->h_set == LV_SIZE_AUTO) || (!row && cont->w_set == LV_SIZE_AUTO)) { @@ -90,7 +126,7 @@ void _lv_flex_refresh(lv_obj_t * cont) lv_coord_t track_size; lv_obj_t * track_first_item; lv_obj_t * next_track_first_item; - bool rev = cont->flex_cont.dir & LV_FLEX_REVERSE; + bool rev = lv_obj_get_flex_reverse(cont); if(place != LV_FLEX_START) { track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll); @@ -117,6 +153,8 @@ void _lv_flex_refresh(lv_obj_t * cont) track_first_item = next_track_first_item; *cross_pos += track_size + gap; } + LV_ASSERT_MEM_INTEGRITY(); + } /********************** @@ -125,18 +163,18 @@ void _lv_flex_refresh(lv_obj_t * cont) static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_size, lv_coord_t * grow_unit, lv_coord_t * track_cross_size) { - lv_flex_dir_t dir = cont->flex_cont.dir; - bool row = (dir & 0x3) == LV_FLEX_DIR_ROW ? true : false; + bool wrap = lv_obj_get_flex_wrap(cont); + bool rev = lv_obj_get_flex_reverse(cont); + lv_coord_t gap = lv_obj_get_flex_gap(cont); + bool row = lv_obj_get_flex_dir(cont) == LV_FLEX_DIR_ROW ? true : false; lv_coord_t(*get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin); - 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; + void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _lv_ll_get_next : _lv_ll_get_prev; 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; uint32_t grow_item_cnt = 0; *track_cross_size = 0; *grow_unit = 0; @@ -186,18 +224,19 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t track_size, lv_coord_t grow_unit) { - lv_flex_dir_t dir = cont->flex_cont.dir; - bool row = (dir & 0x3) == LV_FLEX_DIR_ROW ? true : false; + bool rev = lv_obj_get_flex_reverse(cont); + lv_coord_t gap = lv_obj_get_flex_gap(cont); + bool row = lv_obj_get_flex_dir(cont) == LV_FLEX_DIR_ROW ? true : false; + lv_coord_t(*obj_get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*obj_get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin); void (*area_set_main_size)(lv_area_t *, lv_coord_t) = (row ? lv_area_set_width : lv_area_set_height); lv_coord_t (*area_get_main_size)(const lv_area_t *) = (!row ? lv_area_get_width : lv_area_get_height); lv_style_int_t (*get_margin_start)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top); 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; + void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _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*/ lv_obj_t * item = item_first; /*Just to use a shorter name*/ diff --git a/src/lv_core/lv_flex.h b/src/lv_core/lv_flex.h index 884300f4a..86787d271 100644 --- a/src/lv_core/lv_flex.h +++ b/src/lv_core/lv_flex.h @@ -48,8 +48,10 @@ typedef enum { typedef struct { lv_coord_t gap; - uint32_t place :4; - uint32_t dir :4; + uint8_t dir :2; + uint8_t wrap :1; + uint8_t rev :1; + uint8_t place :3; }lv_flex_cont_t; /********************** @@ -59,6 +61,12 @@ typedef struct { void lv_obj_set_flex_cont(lv_obj_t * obj, lv_flex_dir_t flex_dir, lv_flex_place_t flex_place); void lv_obj_set_flex_gap(lv_obj_t * obj, lv_coord_t gap); void lv_obj_set_flex_item(lv_obj_t * obj, lv_flex_place_t place); + +lv_flex_dir_t lv_obj_get_flex_dir(const lv_obj_t * obj); +lv_flex_place_t lv_obj_get_flex_place(const lv_obj_t * obj); +bool lv_obj_get_flex_wrap(const lv_obj_t * obj); +bool lv_obj_get_flex_reverse(const lv_obj_t * obj); +lv_coord_t lv_obj_get_flex_gap(const lv_obj_t * obj); void _lv_flex_refresh(lv_obj_t * cont); /********************** diff --git a/src/lv_core/lv_grid.c b/src/lv_core/lv_grid.c index dfbe1434e..49ceed944 100644 --- a/src/lv_core/lv_grid.c +++ b/src/lv_core/lv_grid.c @@ -53,7 +53,9 @@ void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - obj->grid = grid; + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); + obj->spec_attr->grid = grid; + _lv_grid_full_refresh(obj); } @@ -62,11 +64,12 @@ void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid) * @param obj pointer to an object * @return the grid, NULL if no grid */ -const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj, const lv_grid_t * grid) +const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return obj->grid; + if(obj->spec_attr) return obj->spec_attr->grid; + return NULL; } @@ -96,9 +99,10 @@ void lv_obj_report_grid_change(const lv_grid_t * grid) */ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out) { - if(cont->grid == NULL) return; - if(cont->grid->col_dsc == NULL || cont->grid->row_dsc == NULL) return; - if(cont->grid->col_dsc_len == 0 || cont->grid->row_dsc_len == 0) return; + lv_grid_t * g = lv_obj_get_grid(cont); + if(g == NULL) return; + if(g->col_dsc == NULL || g->row_dsc == NULL) return; + if(g->col_dsc_len == 0 || g->row_dsc_len == 0) return; if(lv_obj_get_child(cont, NULL) == NULL) { _lv_memset_00(calc_out, sizeof(_lv_grid_calc_t)); @@ -111,11 +115,11 @@ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out) bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false; lv_coord_t cont_w = lv_obj_get_width_fit(cont); - calc_out->grid_w = grid_place(cont_w, auto_w, cont->grid->col_place, cont->grid->col_gap, calc_out->col_num, calc_out->w, calc_out->x); + calc_out->grid_w = grid_place(cont_w, auto_w, g->col_place, g->col_gap, calc_out->col_num, calc_out->w, calc_out->x); bool auto_h = cont->h_set == LV_SIZE_AUTO ? true : false; lv_coord_t cont_h = lv_obj_get_height_fit(cont); - calc_out->grid_h = grid_place(cont_h, auto_h, cont->grid->row_place, cont->grid->row_gap, calc_out->row_num, calc_out->h, calc_out->y); + calc_out->grid_h = grid_place(cont_h, auto_h, g->row_place, g->row_gap, calc_out->row_num, calc_out->h, calc_out->y); LV_ASSERT_MEM_INTEGRITY(); } @@ -139,12 +143,12 @@ void _lv_grid_calc_free(_lv_grid_calc_t * calc) */ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj) { - if(obj->grid == NULL) return false; - if(obj->grid->col_dsc == NULL) return false; + lv_grid_t * g = lv_obj_get_grid(obj); + if(g->col_dsc == NULL) return false; uint32_t i; - for(i = 0; i < obj->grid->col_dsc_len; i++) { - if(LV_GRID_IS_FR(obj->grid->col_dsc[i])) return true; + for(i = 0; i < g->col_dsc_len; i++) { + if(LV_GRID_IS_FR(g->col_dsc[i])) return true; } return false; @@ -157,12 +161,13 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj) */ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj) { - if(obj->grid == NULL) return false; - if(obj->grid->row_dsc == NULL) return false; + lv_grid_t * g = lv_obj_get_grid(obj); + if(g == NULL) return false; + if(g->row_dsc == NULL) return false; uint32_t i; - for(i = 0; i < obj->grid->row_dsc_len; i++) { - if(LV_GRID_IS_FR(obj->grid->row_dsc[i])) return true; + for(i = 0; i < g->row_dsc_len; i++) { + if(LV_GRID_IS_FR(g->row_dsc[i])) return true; } return false; @@ -175,7 +180,7 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj) void _lv_grid_full_refresh(lv_obj_t * cont) { /*Calculate the grid*/ - if(cont->grid == NULL) return; + if(lv_obj_get_grid(cont) == NULL) return; _lv_grid_calc_t calc; _lv_grid_calc(cont, &calc); @@ -213,7 +218,8 @@ void lv_grid_item_refr_pos(lv_obj_t * item) /*Calculate the grid*/ lv_obj_t * cont = lv_obj_get_parent(item); if(cont == NULL) return; - if(cont->grid == NULL) return; + if(cont->spec_attr == NULL) return; + if(cont->spec_attr->grid == NULL) return; _lv_grid_calc_t calc; _lv_grid_calc(cont, &calc); @@ -228,7 +234,7 @@ void lv_grid_item_refr_pos(lv_obj_t * item) static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc) { - const lv_grid_t * grid = cont->grid; + const lv_grid_t * grid = cont->spec_attr->grid; uint32_t i; lv_coord_t cont_w = lv_obj_get_width_fit(cont); @@ -267,7 +273,7 @@ static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc) static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) { - const lv_grid_t * grid = cont->grid; + const lv_grid_t * grid = cont->spec_attr->grid; uint32_t i; calc->row_num = grid->row_dsc_len; @@ -466,7 +472,9 @@ static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t plac */ static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj) { - if(obj->grid == grid || (obj->grid && grid == NULL)) _lv_grid_full_refresh(obj); + if(obj->spec_attr) { + if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj); + } lv_obj_t * child = lv_obj_get_child(obj, NULL); while(child) { diff --git a/src/lv_core/lv_grid.h b/src/lv_core/lv_grid.h index 4b1b6cc5a..e9c25b2f0 100644 --- a/src/lv_core/lv_grid.h +++ b/src/lv_core/lv_grid.h @@ -101,7 +101,7 @@ void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid); * @param obj pointer to an object * @return the grid, NULL if no grid */ -const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj, const lv_grid_t * grid); +const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj); /** diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index 32f906dc5..571ac30ff 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -93,7 +93,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) { - (*obj)->group_p = NULL; + if((*obj)->spec_attr) (*obj)->spec_attr->group_p = NULL; } _lv_ll_clear(&(group->obj_ll)); @@ -119,15 +119,18 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) } /*If the object is already in a group and focused then defocus it*/ - if(obj->group_p) { + lv_group_t * group_cur = lv_obj_get_group(obj); + if(group_cur) { if(lv_obj_is_focused(obj)) { - lv_group_refocus(obj->group_p); + lv_group_refocus(group_cur); LV_LOG_INFO("lv_group_add_obj: assign object to an other group"); } } - obj->group_p = group; + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); + obj->spec_attr->group_p = group; + lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll); LV_ASSERT_MEM(next); if(next == NULL) return; @@ -146,7 +149,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) */ void lv_group_remove_obj(lv_obj_t * obj) { - lv_group_t * g = obj->group_p; + lv_group_t * g = lv_obj_get_group(obj); if(g == NULL) return; if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/ @@ -177,7 +180,7 @@ void lv_group_remove_obj(lv_obj_t * obj) if(*i == obj) { _lv_ll_remove(&g->obj_ll, i); lv_mem_free(i); - obj->group_p = NULL; + if(obj->spec_attr) obj->spec_attr->group_p = NULL; break; } } @@ -199,7 +202,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) { - (*obj)->group_p = NULL; + if((*obj)->spec_attr) (*obj)->spec_attr->group_p = NULL; } _lv_ll_clear(&(group->obj_ll)); @@ -212,7 +215,7 @@ void lv_group_remove_all_objs(lv_group_t * group) void lv_group_focus_obj(lv_obj_t * obj) { if(obj == NULL) return; - lv_group_t * g = obj->group_p; + lv_group_t * g = lv_obj_get_group(obj); if(g == NULL) return; if(g->frozen != 0) return; diff --git a/src/lv_core/lv_indev_scroll.c b/src/lv_core/lv_indev_scroll.c index c9f97e319..4a8518c8e 100644 --- a/src/lv_core/lv_indev_scroll.c +++ b/src/lv_core/lv_indev_scroll.c @@ -81,10 +81,11 @@ void _lv_scroll_handler(lv_indev_proc_t * proc) diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb); } - if((scroll_obj->scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; - if((scroll_obj->scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; - if((scroll_obj->scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; - if((scroll_obj->scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; + lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj); + if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; + if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; + if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; + if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0; /*Respect the scroll limit area*/ scroll_limit_diff(proc, &diff_x, &diff_y); @@ -115,10 +116,13 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) proc->types.pointer.scroll_throw_vect.x = 0; } + lv_scroll_snap_align_t align_x = lv_obj_get_snap_align_x(scroll_obj); + lv_scroll_snap_align_t align_y = lv_obj_get_snap_align_y(scroll_obj); + if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_VER) { proc->types.pointer.scroll_throw_vect.x = 0; /*If no snapping "throw"*/ - if(scroll_obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) { + if(align_y == LV_SCROLL_SNAP_ALIGN_NONE) { proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y * (100 - scroll_throw) / 100; @@ -141,7 +145,7 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) { proc->types.pointer.scroll_throw_vect.y = 0; /*If no snapping "throw"*/ - if(scroll_obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) { + if(align_x == LV_SCROLL_SNAP_ALIGN_NONE) { proc->types.pointer.scroll_throw_vect.x = proc->types.pointer.scroll_throw_vect.x * (100 - scroll_throw) / 100; @@ -166,7 +170,7 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) if(proc->types.pointer.scroll_throw_vect.x == 0 && proc->types.pointer.scroll_throw_vect.y == 0) { /*Revert if scrolled in*/ /*If vertically scrollable and not controlled by snap*/ - if(scroll_obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) { + if(align_y == LV_SCROLL_SNAP_ALIGN_NONE) { lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); if(st > 0 || sb > 0) { @@ -180,7 +184,7 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) } /*If horizontally scrollable and not controlled by snap*/ - if(scroll_obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) { + if(align_x == LV_SCROLL_SNAP_ALIGN_NONE) { lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); if (sl > 0 || sr > 0) { @@ -276,7 +280,7 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc) bool right_en = hor_en; /*The object might have disabled some directions.*/ - lv_dir_t scroll_dir = obj_act->scroll_dir; + lv_dir_t scroll_dir = lv_obj_get_scroll_dir(obj_act); if((scroll_dir & LV_DIR_LEFT) == 0) left_en = false; if((scroll_dir & LV_DIR_RIGHT) == 0) right_en = false; if((scroll_dir & LV_DIR_TOP) == 0) up_en = false; @@ -347,7 +351,7 @@ static void init_scroll_limits(lv_indev_proc_t * proc) } /*With STOP limit the scrolling to the perv and next snap point*/ else { - switch(obj->snap_align_y) { + switch(lv_obj_get_snap_align_y(obj)) { case LV_SCROLL_SNAP_ALIGN_START: proc->types.pointer.scroll_area.y1 = find_snap_point_y(obj, obj->coords.y1 + 1, LV_COORD_MAX, 0); proc->types.pointer.scroll_area.y2 = find_snap_point_y(obj, LV_COORD_MIN, obj->coords.y1 - 1, 0); @@ -368,7 +372,7 @@ static void init_scroll_limits(lv_indev_proc_t * proc) break; } - switch(obj->snap_align_x) { + switch(lv_obj_get_snap_align_x(obj)) { case LV_SCROLL_SNAP_ALIGN_START: proc->types.pointer.scroll_area.x1 = find_snap_point_x(obj, obj->coords.x1, LV_COORD_MAX, 0); proc->types.pointer.scroll_area.x2 = find_snap_point_x(obj, LV_COORD_MIN, obj->coords.x1, 0); @@ -399,7 +403,8 @@ static void init_scroll_limits(lv_indev_proc_t * proc) static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs) { - if(obj->snap_align_x == LV_SCROLL_SNAP_ALIGN_NONE) return 0; + lv_scroll_snap_align_t align = lv_obj_get_snap_align_x(obj); + if(align == LV_SCROLL_SNAP_ALIGN_NONE) return 0; lv_coord_t dist = LV_COORD_MAX; @@ -408,7 +413,7 @@ static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coo if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) { lv_coord_t x_child = 0; lv_coord_t x_parent = 0; - switch(obj->snap_align_x) { + switch(align) { case LV_SCROLL_SNAP_ALIGN_START: x_child = child->coords.x1; x_parent = obj->coords.x1; @@ -431,7 +436,6 @@ static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coo child = lv_obj_get_child_back(obj, child); } - LV_ASSERT_MEM_INTEGRITY(); return dist == LV_COORD_MAX ? 0: -dist; } @@ -447,7 +451,8 @@ static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coo */ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coord_t max, lv_coord_t ofs) { - if(obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) return 0; + lv_scroll_snap_align_t align = lv_obj_get_snap_align_y(obj); + if(align == LV_SCROLL_SNAP_ALIGN_NONE) return 0; lv_coord_t dist = LV_COORD_MAX; @@ -456,7 +461,7 @@ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coo if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) { lv_coord_t y_child = 0; lv_coord_t y_parent = 0; - switch(obj->snap_align_y) { + switch(align) { case LV_SCROLL_SNAP_ALIGN_START: y_child = child->coords.y1; y_parent = obj->coords.y1; @@ -480,7 +485,6 @@ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coo child = lv_obj_get_child_back(obj, child); } - LV_ASSERT_MEM_INTEGRITY(); return dist == LV_COORD_MAX ? 0 : -dist; } diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 427618dfa..ae1259995 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -204,16 +204,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) _lv_memset_00(new_obj, sizeof(lv_obj_t)); -#if LV_USE_BIDI - new_obj->base_dir = LV_BIDI_BASE_DIR_DEF; -#else - new_obj->base_dir = LV_BIDI_DIR_LTR; -#endif - /*Set the callbacks*/ new_obj->signal_cb = lv_obj_signal; new_obj->design_cb = lv_obj_design; - new_obj->event_cb = NULL; /*Set coordinates to full screen size*/ new_obj->coords.x1 = 0; @@ -225,10 +218,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); - if(parent->rare_attr == NULL) { - parent->rare_attr = lv_obj_allocate_rare_attr(parent); + if(parent->spec_attr == NULL) { + parent->spec_attr = lv_obj_allocate_rare_attr(parent); } - new_obj = _lv_ll_ins_head(&parent->rare_attr->child_ll); + new_obj = _lv_ll_ins_head(&parent->spec_attr->child_ll); LV_ASSERT_MEM(new_obj); if(new_obj == NULL) return NULL; @@ -236,16 +229,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->parent = parent; -#if LV_USE_BIDI - new_obj->base_dir = LV_BIDI_DIR_INHERIT; -#else - new_obj->base_dir = LV_BIDI_DIR_LTR; -#endif - /*Set the callbacks (signal:cb is required in `lv_obj_get_base_dir` if `LV_USE_ASSERT_OBJ` is enabled)*/ new_obj->signal_cb = lv_obj_signal; new_obj->design_cb = lv_obj_design; - new_obj->event_cb = NULL; new_obj->coords.y1 = parent->coords.y1; new_obj->coords.y2 = parent->coords.y1 + LV_OBJ_DEF_HEIGHT; @@ -264,25 +250,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->ext_draw_pad = 0; -#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL - _lv_memset_00(&new_obj->ext_click_pad, sizeof(new_obj->ext_click_pad)); -#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY - new_obj->ext_click_pad = 0; -#endif - - /*Init. user date*/ -#if LV_USE_USER_DATA - _lv_memset_00(&new_obj->user_data, sizeof(lv_obj_user_data_t)); -#endif - - -#if LV_USE_GROUP - new_obj->group_p = NULL; -#endif - /*Set attributes*/ - new_obj->scroll_mode = LV_SCROLL_MODE_AUTO; - new_obj->scroll_dir = LV_DIR_ALL; new_obj->flags = LV_OBJ_FLAG_CLICKABLE; new_obj->flags |= LV_OBJ_FLAG_SNAPABLE; new_obj->flags |= LV_OBJ_FLAG_PRESS_LOCK; @@ -309,26 +277,12 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) lv_area_copy(&new_obj->coords, ©->coords); new_obj->ext_draw_pad = copy->ext_draw_pad; - #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL - lv_area_copy(&new_obj->ext_click_pad, ©->ext_click_pad); - #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY - new_obj->ext_click_pad = copy->ext_click_pad; - #endif - - /*Set user data*/ - #if LV_USE_USER_DATA - _lv_memcpy(&new_obj->user_data, ©->user_data, sizeof(lv_obj_user_data_t)); - #endif - /*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied in the derived - * object type (e.g. `lv_btn`)*/ - new_obj->event_cb = copy->event_cb; - new_obj->flags = copy->flags; #if LV_USE_GROUP /*Add to the same group*/ - if(copy->group_p != NULL) { - lv_group_add_obj(copy->group_p, new_obj); + if(copy->spec_attr && copy->spec_attr->group_p) { + lv_group_add_obj(copy->spec_attr->group_p, new_obj); } #endif @@ -559,8 +513,8 @@ 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); + if(parent->spec_attr == NULL) { + parent->spec_attr = lv_obj_allocate_rare_attr(parent); } lv_obj_t * old_par = obj->parent; @@ -667,12 +621,14 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL - obj->ext_click_pad.x1 = left; - obj->ext_click_pad.x2 = right; - obj->ext_click_pad.y1 = top; - obj->ext_click_pad.y2 = bottom; + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); + objrare_attr->->ext_click_pad.x1 = left; + objrare_attr->->ext_click_pad.x2 = right; + objrare_attr->->ext_click_pad.y1 = top; + objrare_attr->->ext_click_pad.y2 = bottom; #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY - obj->ext_click_pad = LV_MATH_MAX4(left, right, top, bottom); + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); + obj->spec_attr->ext_click_pad = LV_MATH_MAX4(left, right, top, bottom); #else LV_UNUSED(obj); LV_UNUSED(left); @@ -704,7 +660,8 @@ void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir) return; } - obj->base_dir = dir; + lv_obj_allocate_rare_attr(obj); + obj->spec_attr->base_dir = dir; lv_signal_send(obj, LV_SIGNAL_BASE_DIR_CHG, NULL); /* Notify the children about the parent base dir has changed. @@ -841,8 +798,9 @@ void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state) void lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + if(obj->spec_attr == NULL) obj->spec_attr = lv_obj_allocate_rare_attr(obj); - obj->event_cb = event_cb; + obj->spec_attr->event_cb = event_cb; } /** @@ -859,7 +817,7 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_res_t res; - res = lv_event_send_func(obj->event_cb, obj, event, data); + res = lv_event_send_func(lv_obj_get_event_cb(obj), obj, event, data); return res; } @@ -1052,21 +1010,27 @@ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size) * @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_obj_spec_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; + if(obj->spec_attr == NULL) { + static uint32_t x = 0; + x++; + obj->spec_attr = lv_mem_alloc(sizeof(lv_obj_spec_attr_t)); + LV_ASSERT_MEM(obj->spec_attr); + if(obj->spec_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)); + _lv_memset_00(obj->spec_attr, sizeof(lv_obj_spec_attr_t)); + _lv_ll_init(&(obj->spec_attr->child_ll), sizeof(lv_obj_t)); + + obj->spec_attr->scroll_dir = LV_DIR_ALL; + obj->spec_attr->base_dir = LV_BIDI_DIR_INHERIT; + obj->spec_attr->scroll_mode = LV_SCROLL_MODE_AUTO; } - return obj->rare_attr; + return obj->spec_attr; } @@ -1272,7 +1236,8 @@ lv_coord_t lv_obj_get_ext_click_area(const lv_obj_t * obj, lv_dir_t dir) return 0; #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY LV_UNUSED(dir); - return obj->ext_click_pad; + if(obj->spec_attr) return obj->spec_attr->ext_click_pad; + else return 0; #else switch(dir) { case LV_DIR_LEFT: @@ -1299,28 +1264,17 @@ lv_coord_t lv_obj_get_ext_click_area(const lv_obj_t * obj, lv_dir_t dir) */ bool _lv_obj_is_click_point_on(lv_obj_t * obj, const lv_point_t * point) { -#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY - lv_area_t ext_area; - ext_area.x1 = obj->coords.x1 - obj->ext_click_pad; - ext_area.x2 = obj->coords.x2 + obj->ext_click_pad; - ext_area.y1 = obj->coords.y1 - obj->ext_click_pad; - ext_area.y2 = obj->coords.y2 + obj->ext_click_pad; - - if(!_lv_area_is_point_on(&ext_area, point, 0)) { -#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL - lv_area_t ext_area; - ext_area.x1 = obj->coords.x1 - obj->ext_click_pad.x1; - ext_area.x2 = obj->coords.x2 + obj->ext_click_pad.x2; - ext_area.y1 = obj->coords.y1 - obj->ext_click_pad.y1; - ext_area.y2 = obj->coords.y2 + obj->ext_click_pad.y2; - - if(!_lv_area_is_point_on(&ext_area, point, 0)) { +#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_OFF + return _lv_area_is_point_on(&obj->coords, point, 0); #else - if(!_lv_area_is_point_on(&obj->coords, point, 0)) { + lv_area_t ext_area; + ext_area.x1 = obj->coords.x1 - lv_obj_get_ext_click_area(obj, LV_DIR_LEFT); + ext_area.x2 = obj->coords.x2 + lv_obj_get_ext_click_area(obj, LV_DIR_RIGHT); + ext_area.y1 = obj->coords.y1 - lv_obj_get_ext_click_area(obj, LV_DIR_TOP); + ext_area.y2 = obj->coords.y2 + lv_obj_get_ext_click_area(obj, LV_DIR_BOTTOM); + + return _lv_area_is_point_on(&ext_area, point, 0); #endif - return false; - } - return true; } /** @@ -1362,11 +1316,15 @@ lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + if(obj->spec_attr == NULL) return LV_BIDI_DIR_LTR; #if LV_USE_BIDI const lv_obj_t * parent = obj; while(parent) { - if(parent->base_dir != LV_BIDI_DIR_INHERIT) return parent->base_dir; + /*If the base dir set use it. If not set assume INHERIT so got the next parent*/ + if(parent->spec_attr) { + if(parent->spec_attr->base_dir != LV_BIDI_DIR_INHERIT) return parent->spec_attr->base_dir; + } parent = lv_obj_get_parent(parent); } @@ -1418,7 +1376,8 @@ lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return obj->event_cb; + if(obj->spec_attr) return obj->spec_attr->event_cb; + else return NULL; } /*------------------ @@ -1477,9 +1436,10 @@ void lv_obj_get_type(const lv_obj_t * obj, lv_obj_type_t * buf) */ lv_obj_user_data_t lv_obj_get_user_data(const lv_obj_t * obj) { + static lv_obj_user_data_t empty = {0}; LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - return obj->user_data; + if(obj->spec_attr) return obj->spec_attr->user_data; + else return empty; } /** @@ -1491,7 +1451,8 @@ lv_obj_user_data_t * lv_obj_get_user_data_ptr(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return (lv_obj_user_data_t *)&obj->user_data; + if(obj->spec_attr) return obj->spec_attr->user_data; + return &obj->spec_attr->user_data; } /** @@ -1503,7 +1464,8 @@ void lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - _lv_memcpy(&obj->user_data, &data, sizeof(lv_obj_user_data_t)); + if(obj->spec_attr == NULL) lv_obj_allocate_rare_attr(obj); + _lv_memcpy(&obj->spec_attr->user_data, &data, sizeof(lv_obj_user_data_t)); } #endif @@ -1517,7 +1479,8 @@ void * lv_obj_get_group(const lv_obj_t * obj) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_USE_GROUP - return obj->group_p; + if(obj->spec_attr) return obj->spec_attr->group_p; + else return NULL; #else LV_UNUSED(obj); return NULL; @@ -1534,8 +1497,9 @@ bool lv_obj_is_focused(const lv_obj_t * obj) LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_USE_GROUP - if(obj->group_p) { - if(lv_group_get_focused(obj->group_p) == obj) return true; + lv_group_t * g = lv_obj_get_group(obj); + if(g) { + if(lv_group_get_focused(g) == obj) return true; } return false; #else @@ -1565,7 +1529,7 @@ 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) { - if(obj->rare_attr) return &obj->rare_attr->child_ll; + if(obj->spec_attr) return &obj->spec_attr->child_ll; else return NULL; } @@ -1840,7 +1804,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area #if GRID_DEBUG /*Draw the grid cells*/ - if(obj->grid) { + if(lv_obj_get_grid(obj)) { _lv_grid_calc_t calc; _lv_grid_calc(obj, &calc); @@ -1887,7 +1851,7 @@ static void base_dir_refr_children(lv_obj_t * obj) { lv_obj_t * child; _LV_LL_READ(_lv_obj_get_child_ll(obj), child) { - if(child->base_dir == LV_BIDI_DIR_INHERIT) { + if(lv_obj_get_base_dir(child) == LV_BIDI_DIR_INHERIT) { lv_signal_send(child, LV_SIGNAL_BASE_DIR_CHG, NULL); base_dir_refr_children(child); } @@ -2006,8 +1970,8 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) lv_obj_set_size(child, child->w_set, child->h_set); } } - if(obj->grid) _lv_grid_full_refresh(obj); - if(obj->flex_cont.dir) _lv_flex_refresh(obj); + if(lv_obj_get_grid(obj)) _lv_grid_full_refresh(obj); + if(lv_obj_get_flex_dir(obj) != LV_FLEX_DIR_NONE) _lv_flex_refresh(obj); } } else if(sign == LV_SIGNAL_CHILD_CHG) { @@ -2020,7 +1984,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) } /*If the changed children was a grid item refresh this objects grid*/ - if(obj->grid) { + if(lv_obj_get_grid(obj)) { lv_obj_t * child = param; if(child) { if(_lv_obj_is_grid_item(child)) _lv_grid_full_refresh(obj); @@ -2046,7 +2010,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) else if(sign == LV_SIGNAL_STYLE_CHG) { if(_lv_obj_is_grid_item(obj)) _lv_grid_full_refresh(obj); - if(obj->grid) _lv_grid_full_refresh(obj); + if(lv_obj_get_grid(obj)) _lv_grid_full_refresh(obj); /*Reposition non grid objects on by one*/ lv_obj_t * child; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 5fcdb9ce0..65fc1e055 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -169,20 +169,6 @@ enum { typedef uint8_t lv_state_t; -enum { - LV_DIR_NONE = 0x00, - LV_DIR_LEFT = (1 << 0), - LV_DIR_RIGHT = (1 << 1), - LV_DIR_TOP = (1 << 2), - LV_DIR_BOTTOM = (1 << 3), - LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT, - LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM, - LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER, -}; - -typedef uint8_t lv_dir_t; - - enum { LV_OBJ_FLAG_HIDDEN = (1 << 0), LV_OBJ_FLAG_CLICKABLE = (1 << 1), @@ -210,22 +196,21 @@ typedef uint16_t lv_obj_flag_t; 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; +#if LV_USE_GROUP != 0 + void * group_p; +#endif -struct _lv_obj_t { - lv_obj_rare_attr_t * rare_attr; - struct _lv_obj_t * parent; /**< Pointer to the parent object*/ +#if LV_USE_USER_DATA + lv_obj_user_data_t user_data; /**< Custom user data for object. */ +#endif - lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/ + const lv_grid_t * grid; lv_event_cb_t event_cb; /**< Event callback function */ - lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ - lv_design_cb_t design_cb; /**< Object type specific design function*/ - void * ext_attr; /**< Object type specific extended data*/ - lv_style_list_t style_list; + lv_flex_cont_t flex_cont; + lv_point_t scroll; /**< The current X/Y scroll offset*/ #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY uint8_t ext_click_pad; /**< Extra click padding in all direction */ @@ -233,15 +218,28 @@ struct _lv_obj_t { lv_area_t ext_click_pad; /**< Extra click padding area. */ #endif - lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */ - - /*Attributes and states*/ - lv_obj_flag_t flags; lv_scroll_mode_t scroll_mode :2; /**< How to display scrollbars*/ lv_scroll_snap_align_t snap_align_x : 2; lv_scroll_snap_align_t snap_align_y : 2; lv_scroll_dir_t scroll_dir :4; lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */ +}lv_obj_spec_attr_t; + + +struct _lv_obj_t { + lv_obj_spec_attr_t * spec_attr; + struct _lv_obj_t * parent; /**< Pointer to the parent object*/ + + lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/ + + lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ + lv_design_cb_t design_cb; /**< Object type specific design function*/ + + void * ext_attr; /**< Object type specific extended data*/ + lv_style_list_t style_list; + + /*Attributes and states*/ + lv_obj_flag_t flags; lv_state_t state; @@ -250,18 +248,7 @@ struct _lv_obj_t { lv_coord_t w_set; lv_coord_t h_set; -#if LV_USE_GROUP != 0 - void * group_p; -#endif - - -#if LV_USE_USER_DATA - lv_obj_user_data_t user_data; /**< Custom user data for object. */ -#endif - - const lv_grid_t * grid; - - lv_flex_cont_t flex_cont; + lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */ }; enum { @@ -553,7 +540,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); +lv_obj_spec_attr_t * lv_obj_allocate_rare_attr(lv_obj_t * obj); /*======================= * Getter functions *======================*/ diff --git a/src/lv_core/lv_obj_draw.c b/src/lv_core/lv_obj_draw.c index ac356a140..2481bc7c5 100644 --- a/src/lv_core/lv_obj_draw.c +++ b/src/lv_core/lv_obj_draw.c @@ -437,8 +437,10 @@ void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area) lv_coord_t obj_h = lv_obj_get_height(obj); lv_coord_t obj_w = lv_obj_get_width(obj); + lv_scroll_dir_t dir = lv_obj_get_scroll_dir(obj); + bool ver_draw = false; - if((obj->scroll_dir & LV_DIR_VER) && + if((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))) { @@ -447,7 +449,7 @@ void _lv_obj_draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area) bool hor_draw = false; - if((obj->scroll_dir & LV_DIR_HOR) && + if((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))) { diff --git a/src/lv_core/lv_obj_pos.c b/src/lv_core/lv_obj_pos.c index 8aaabcdb1..d6392ed5b 100644 --- a/src/lv_core/lv_obj_pos.c +++ b/src/lv_core/lv_obj_pos.c @@ -593,7 +593,7 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_o /*Get the grid size of the object has a defined grid*/ lv_coord_t grid_w = 0; lv_coord_t grid_h = 0; - if(obj->grid) { + if(lv_obj_get_grid(obj)) { _lv_grid_calc_t calc; _lv_grid_calc(obj, &calc); grid_w = calc.grid_w + lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN) + lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN); @@ -714,11 +714,12 @@ bool _lv_obj_is_grid_item(lv_obj_t * obj) { lv_obj_t * cont = lv_obj_get_parent(obj); if(cont == NULL) return false; - if(cont->grid == NULL) return false; - if(cont->grid->col_dsc == NULL) return false; - if(cont->grid->row_dsc == NULL) return false; - if(cont->grid->row_dsc_len == 0) return false; - if(cont->grid->col_dsc_len == 0) return false; + const lv_grid_t * g = lv_obj_get_grid(obj); + if(g == NULL) return false; + if(g->col_dsc == NULL) return false; + if(g->row_dsc == NULL) return false; + if(g->row_dsc_len == 0) return false; + if(g->col_dsc_len == 0) return false; if(LV_COORD_IS_GRID(obj->x_set) == false || LV_COORD_IS_GRID(obj->y_set) == false) return false; return true; } @@ -733,7 +734,7 @@ bool _lv_obj_is_flex_item(struct _lv_obj_t * obj) { lv_obj_t * cont = lv_obj_get_parent(obj); if(cont == NULL) return false; - if(cont->flex_cont.dir == LV_FLEX_DIR_NONE) return false; + if(lv_obj_get_flex_dir(cont) == LV_FLEX_DIR_NONE) return false; if(LV_COORD_IS_FLEX(obj->x_set) == false || LV_COORD_IS_FLEX(obj->y_set) == false) return false; return true; } diff --git a/src/lv_core/lv_obj_scroll.c b/src/lv_core/lv_obj_scroll.c index a192ed4ad..6fb485754 100644 --- a/src/lv_core/lv_obj_scroll.c +++ b/src/lv_core/lv_obj_scroll.c @@ -47,23 +47,13 @@ void lv_obj_set_scroll_mode(lv_obj_t * obj, lv_scroll_mode_t mode) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - if(obj->scroll_mode == mode) return; - obj->scroll_mode = mode; + lv_obj_allocate_rare_attr(obj); + + if(obj->spec_attr->scroll_mode == mode) return; + obj->spec_attr->scroll_mode = mode; lv_obj_invalidate(obj); } -/** - * Get how the scrollbars should behave. - * @param obj pointer to an object - * @return mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE - */ -lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - return obj->scroll_mode; -} - /** * Moves all children with horizontally or vertically. * It doesn't take into account any limits so any values are possible @@ -75,11 +65,11 @@ void _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) { if(x == 0 && y == 0) return; - if(obj->rare_attr == NULL) { - obj->rare_attr = lv_obj_allocate_rare_attr(obj); + if(obj->spec_attr == NULL) { + obj->spec_attr = lv_obj_allocate_rare_attr(obj); } - obj->rare_attr->scroll.x += x; - obj->rare_attr->scroll.y += y; + obj->spec_attr->scroll.x += x; + obj->spec_attr->scroll.y += y; _lv_obj_move_children_by(obj, x, y); lv_res_t res = lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL); @@ -177,8 +167,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) { - if(obj->rare_attr == NULL) return 0; - return -obj->rare_attr->scroll.y; + if(obj->spec_attr == NULL) return 0; + return -obj->spec_attr->scroll.y; } /** @@ -226,8 +216,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) { - if(obj->rare_attr == NULL) return 0; - return -obj->rare_attr->scroll.x; + if(obj->spec_attr == NULL) return 0; + return -obj->spec_attr->scroll.x; } /** @@ -281,6 +271,52 @@ void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end) end->y = a ? -a->end : lv_obj_get_scroll_top(obj); } +lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->scroll_dir; + else return LV_DIR_ALL; +} + +void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir) +{ + lv_obj_allocate_rare_attr(obj); + + if(dir != obj->spec_attr->scroll_dir) { + obj->spec_attr->scroll_dir = dir; + lv_obj_invalidate(obj); + } +} + +lv_scroll_mode_t lv_obj_get_scroll_mode(const struct _lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->scroll_mode; + else return LV_SCROLL_MODE_AUTO; +} + +lv_scroll_snap_align_t lv_obj_get_snap_align_x(const struct _lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->snap_align_x; + else return LV_SCROLL_SNAP_ALIGN_NONE; +} +void lv_obj_set_snap_align_x(struct _lv_obj_t * obj, lv_scroll_snap_align_t align) +{ + lv_obj_allocate_rare_attr(obj); + obj->spec_attr->snap_align_x = align; +} + +lv_scroll_snap_align_t lv_obj_get_snap_align_y(const struct _lv_obj_t * obj) +{ + if(obj->spec_attr) return obj->spec_attr->snap_align_y; + else return LV_SCROLL_SNAP_ALIGN_NONE; +} + +void lv_obj_set_snap_align_y(struct _lv_obj_t * obj, lv_scroll_snap_align_t align) +{ + lv_obj_allocate_rare_attr(obj); + obj->spec_attr->snap_align_y = align; +} + + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_core/lv_obj_scroll.h b/src/lv_core/lv_obj_scroll.h index 39ce98686..b357b4aa9 100644 --- a/src/lv_core/lv_obj_scroll.h +++ b/src/lv_core/lv_obj_scroll.h @@ -55,12 +55,6 @@ typedef uint8_t lv_scroll_snap_align_t; */ void lv_obj_set_scroll_mode(struct _lv_obj_t * obj, lv_scroll_mode_t mode); -/** - * Get how the scrollbars should behave. - * @param obj pointer to an object - * @return mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE - */ -lv_scroll_mode_t lv_obj_get_scroll_mode(struct _lv_obj_t * obj); /** * Moves all children with horizontally or vertically. @@ -148,6 +142,16 @@ lv_coord_t lv_obj_get_scroll_right(struct _lv_obj_t * obj); */ void lv_obj_get_scroll_end(struct _lv_obj_t * obj, lv_point_t * end); + +lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj); +void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir); +lv_scroll_mode_t lv_obj_get_scroll_mode(const struct _lv_obj_t * obj); +lv_scroll_snap_align_t lv_obj_get_snap_align_x(const struct _lv_obj_t * obj); +void lv_obj_set_snap_align_x(struct _lv_obj_t * obj, lv_scroll_snap_align_t align); +lv_scroll_snap_align_t lv_obj_get_snap_align_y(const struct _lv_obj_t * obj); +void lv_obj_set_snap_align_y(struct _lv_obj_t * obj, lv_scroll_snap_align_t align); + + /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_area.h b/src/lv_misc/lv_area.h index c0602f644..86926d206 100644 --- a/src/lv_misc/lv_area.h +++ b/src/lv_misc/lv_area.h @@ -78,6 +78,19 @@ enum { }; typedef uint8_t lv_align_t; +enum { + LV_DIR_NONE = 0x00, + LV_DIR_LEFT = (1 << 0), + LV_DIR_RIGHT = (1 << 1), + LV_DIR_TOP = (1 << 2), + LV_DIR_BOTTOM = (1 << 3), + LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT, + LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM, + LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER, +}; + +typedef uint8_t lv_dir_t; + /********************** * GLOBAL PROTOTYPES diff --git a/src/lv_misc/lv_mem.c b/src/lv_misc/lv_mem.c index 761440723..47d7bace3 100644 --- a/src/lv_misc/lv_mem.c +++ b/src/lv_misc/lv_mem.c @@ -161,6 +161,11 @@ void * lv_mem_alloc(size_t size) return &zero_mem; } +// last_ent = NULL; + static uint32_t c = 0; + c++; +// if(c%10 == 0) printf("alloc:%d\n", c); + #ifdef LV_ARCH_64 /*Round the size up to 8*/ size = (size + 7) & (~0x7); @@ -171,27 +176,10 @@ void * lv_mem_alloc(size_t size) void * alloc = NULL; #if LV_MEM_CUSTOM == 0 - static uint32_t defr = 0; - defr++; - if(defr > LV_MEM_FULL_DEFRAG_CNT) { - defr = 0; - lv_mem_defrag(); - } alloc = alloc_core(size); if(alloc == NULL) { - LV_LOG_WARN("Perform defrag"); - lv_mem_monitor_t mon; - - lv_mem_monitor(&mon); - printf("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n", - (int)mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct, - (int)mon.free_biggest_size); + LV_LOG_TRACE("No more memory, try to defrag"); lv_mem_defrag(); - - lv_mem_monitor(&mon); - printf("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n", - (int)mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct, - (int)mon.free_biggest_size); alloc = alloc_core(size); } @@ -216,7 +204,12 @@ void * lv_mem_alloc(size_t size) #endif if(alloc == NULL) { - LV_LOG_WARN("Couldn't allocate memory"); + LV_LOG_WARN("Couldn't allocate memory (%d bytes)", size); + lv_mem_monitor_t mon; + lv_mem_monitor(&mon); + LV_LOG_WARN("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n", + (int)mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct, + (int)mon.free_biggest_size); } else { #if LV_MEM_CUSTOM == 0 @@ -241,19 +234,23 @@ void lv_mem_free(const void * data) if(data == &zero_mem) return; if(data == NULL) return; -#if LV_MEM_ADD_JUNK - _lv_memset((void *)data, 0xbb, _lv_mem_get_size(data)); -#endif - - #if LV_ENABLE_GC == 0 /*e points to the header*/ lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t)); +# if LV_MEM_ADD_JUNK + _lv_memset((void *)data, 0xbb, _lv_mem_get_size(data)); +# endif #endif -/*Use custom, user defined free function*/ #if LV_MEM_CUSTOM == 0 e->header.s.used = 0; + + static uint32_t defr = 0; + defr++; + if(defr > LV_MEM_FULL_DEFRAG_CNT) { + defr = 0; + lv_mem_defrag(); + } #else #if LV_ENABLE_GC == 0 /*e points to the header*/ @@ -387,7 +384,7 @@ lv_res_t lv_mem_test(void) lv_mem_ent_t * e; e = ent_get_next(NULL); while(e) { - if(e->header.s.d_size > LV_MEM_SIZE) { + if( e->header.s.d_size > LV_MEM_SIZE) { return LV_RES_INV; } uint8_t * e8 = (uint8_t *) e; diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index c9b9837ae..954eba29f 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -407,6 +407,7 @@ static bool lv_task_exec(lv_task_t * task) task_deleted = false; task_created = false; if(task->task_cb) task->task_cb(task); + LV_ASSERT_MEM_INTEGRITY(); /*Delete if it was a one shot lv_task*/ if(task_deleted == false) { /*The task might be deleted by itself as well*/