1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

add grid fill

This commit is contained in:
Gabor Kiss-Vamosi 2020-09-16 22:34:45 +02:00
parent 1b15a7b875
commit ab08796736
3 changed files with 113 additions and 37 deletions

View File

@ -120,8 +120,8 @@ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
calc_implicit_rows(cont, calc_out);
}
else if(!cont->grid->col_dsc && cont->grid->row_dsc) {
calc_implicit_cols(cont, calc_out);
calc_explicit_rows(cont, calc_out);
calc_implicit_cols(cont, calc_out);
}
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
@ -183,6 +183,37 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
return false;
}
/**
* Check if the object's grid columns are "fill" type
* @param obj pointer to an object
* @return true: fill type; false: not fill type
*/
bool _lv_grid_has_fill_col(struct _lv_obj_t * obj)
{
if(obj->grid == NULL) return false;
if(obj->grid->col_dsc == NULL) return false;
if(obj->grid->col_dsc_len != 1) return false;
if(_GRID_IS_FILL(obj->grid->col_dsc[0]) == false) return false;
return true;
}
/**
* Check if the object's grid rows are "fill" type
* @param obj pointer to an object
* @return true: fill type; false: not fill type
*/
bool _lv_grid_has_fill_row(struct _lv_obj_t * obj)
{
if(obj->grid == NULL) return false;
if(obj->grid->row_dsc == NULL) return false;
if(obj->grid->row_dsc_len != 1) return false;
if(_GRID_IS_FILL(obj->grid->row_dsc[0]) == false) return false;
return true;
}
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
@ -246,15 +277,33 @@ static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
const lv_grid_t * grid = cont->grid;
uint32_t i;
lv_coord_t cont_w = lv_obj_get_width_fit(cont);
bool filled = false;
if(grid->col_dsc_len == 1 && _GRID_IS_FILL(grid->col_dsc[0])) filled = true;
if(filled) {
lv_coord_t fill_w = _GRID_GET_FILL(grid->col_dsc[0]);
/* Get number of tracks fitting to the content
* Add the gap to cont_w because here is no gap after the last track so compensate it*/
calc->col_num = (cont_w + grid->col_gap) / (fill_w + grid->col_gap);
} else {
calc->col_num = grid->col_dsc_len;
}
calc->x = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num);
calc->w = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num);
/*If filled, it's simple: every track has fill size*/
if(filled) {
lv_coord_t fill_w = _GRID_GET_FILL(grid->col_dsc[0]);
for(i = 0; i < calc->col_num; i++) {
calc->w[i] = fill_w;
}
} else {
uint32_t col_fr_cnt = 0;
lv_coord_t grid_w = 0;
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
for(i = 0; i < grid->col_dsc_len; i++) {
for(i = 0; i < calc->col_num; i++) {
lv_coord_t x = grid->col_dsc[i];
if(_GRID_IS_FR(x)) col_fr_cnt += _GRID_GET_FR(x);
else {
@ -263,10 +312,10 @@ static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
}
}
lv_coord_t cont_w = lv_obj_get_width_fit(cont) - grid->col_gap * (grid->col_dsc_len - 1);
cont_w -= grid->col_gap * (calc->col_num - 1);
lv_coord_t free_w = cont_w - grid_w;
for(i = 0; i < grid->col_dsc_len; i++) {
for(i = 0; i < calc->col_num; i++) {
lv_coord_t x = grid->col_dsc[i];
if(_GRID_IS_FR(x)) {
if(auto_w) calc->w[i] = 0; /*Fr is considered zero if the cont has auto width*/
@ -277,6 +326,7 @@ static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
}
}
}
}
static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
{
@ -355,7 +405,7 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
const lv_grid_t * grid = cont->grid;
uint32_t child_cnt = lv_obj_count_children(cont);
calc->row_num = ((child_cnt + grid->col_dsc_len - 1) / grid->col_dsc_len); /*+ grid->col_dsc_len - 1 to round up*/
calc->row_num = ((child_cnt + calc->col_num - 1) / calc->col_num); /*+ grid->col_dsc_len - 1 to round up*/
calc->h = _lv_mem_buf_get(sizeof(lv_coord_t) * (calc->row_num + 1)); /*+1 to allow some limit checks later*/
calc->y = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num);
@ -370,7 +420,7 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
else h = lv_obj_get_height(child);
calc->h[row_i] = LV_MATH_MAX(calc->h[row_i], h);
col_i++;
if(col_i == grid->col_dsc_len) {
if(col_i == calc->col_num) {
col_i = 0;
row_i++;
calc->h[row_i] = 0;
@ -413,12 +463,12 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
if(cont->grid->row_dsc == NULL) {
hint->col++;
if(hint->col >= cont->grid->col_dsc_len) {
if(hint->col >= calc->col_num) {
hint->col = 0;
hint->row++;
}
} else {
if(hint->row >= cont->grid->row_dsc_len) {
if(hint->row >= calc->row_num) {
hint->row = 0;
hint->col++;
}
@ -438,11 +488,11 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
}
if(cont->grid->row_dsc == NULL) {
col_pos = child_id % cont->grid->col_dsc_len;
row_pos = child_id / cont->grid->col_dsc_len;
col_pos = child_id % calc->col_num;
row_pos = child_id / calc->col_num;
} else {
col_pos = child_id / cont->grid->row_dsc_len;
row_pos = child_id % cont->grid->row_dsc_len;
col_pos = child_id / calc->row_num;
row_pos = child_id % calc->row_num;
}
}
}
@ -452,7 +502,7 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
lv_coord_t col_w = col_x2 - col_x1;
lv_coord_t row_y1 = calc->y[row_pos];
lv_coord_t row_y2 = calc->y[row_pos + row_span - 1] + calc->h[col_pos + col_span - 1];
lv_coord_t row_y2 = calc->y[row_pos + row_span - 1] + calc->h[row_pos + row_span - 1];
lv_coord_t row_h = row_y2 - row_y1;
uint8_t x_flag = _GRID_GET_CELL_FLAG(item->x_set);
@ -549,6 +599,7 @@ static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t plac
/*With spaced placements gap will be calculated from the remaining space*/
if(place == LV_GRID_SPACE_AROUND || place == LV_GRID_SPACE_BETWEEN || place == LV_GRID_SPACE_EVENLY) {
gap = 0;
if(track_num == 1) place = LV_GRID_CENTER;
}
/*Get the full grid size with gap*/

View File

@ -46,11 +46,15 @@ extern "C" {
#define _GRID_CELL_SIZE_FR 1 /* The cell size is set in free units*/
#define LV_GRID_FR(x) (LV_COORD_MAX + (x))
#define LV_GRID_FILL(x) (LV_COORD_MAX + 256 + (x))
#define _GRID_FR_MAX 256
#define _GRID_IS_PX(x) ((_GRID_IS_FR(x) == false) && (_GRID_IS_AUTO(x) == false) ? true : false)
#define _GRID_IS_FR(x) (x > LV_COORD_MAX ? true : false)
#define _GRID_IS_FR(x) ((x) > LV_COORD_MAX && (x) < LV_COORD_MAX + _GRID_FR_MAX ? true : false)
#define _GRID_IS_FILL(x) ((x) > LV_COORD_MAX + _GRID_FR_MAX ? true : false)
#define _GRID_IS_AUTO(x) (x == LV_GRID_AUTO ? true : false)
#define _GRID_GET_FR(x) ((x) - LV_COORD_MAX)
#define _GRID_GET_FILL(x) ((x) - LV_COORD_MAX - _GRID_FR_MAX)
/**
@ -86,6 +90,7 @@ typedef struct {
lv_coord_t row_gap;
uint8_t col_place;
uint8_t row_place;
}lv_grid_t;
typedef struct {
@ -139,6 +144,20 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj);
/**
* Check if the object's grid columns are "fill" type
* @param obj pointer to an object
* @return true: fill type; false: not fill type
*/
bool _lv_grid_has_fill_col(struct _lv_obj_t * obj);
/**
* Check if the object's grid rows are "fill" type
* @param obj pointer to an object
* @return true: fill type; false: not fill type
*/
bool _lv_grid_has_fill_row(struct _lv_obj_t * obj);
void _lv_grid_full_refresh(lv_obj_t * cont);
void lv_grid_item_refr_pos(lv_obj_t * item);

View File

@ -1883,8 +1883,14 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_obj_clear_state(obj, LV_STATE_FOCUSED | LV_STATE_EDITED);
}
else if(sign == LV_SIGNAL_COORD_CHG) {
if(param && ((lv_area_get_width(param) != lv_obj_get_width(obj) && _lv_grid_has_fr_col(obj)) ||
(lv_area_get_height(param) != lv_obj_get_height(obj) && _lv_grid_has_fr_row(obj))))
bool col_fr = _lv_grid_has_fr_col(obj);
bool col_fill = _lv_grid_has_fill_col(obj);
bool row_fr = _lv_grid_has_fr_row(obj);
bool row_fill = _lv_grid_has_fill_row(obj);
if(param == NULL ||
(lv_area_get_width(param) != lv_obj_get_width(obj) && (col_fr || col_fill)) ||
(lv_area_get_height(param) != lv_obj_get_height(obj) && (row_fr || row_fill)))
{
_lv_grid_full_refresh(obj);
}