mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
add flexbox layout and percentage size
This commit is contained in:
parent
7b48464241
commit
ae452cbc22
262
src/lv_core/lv_flex.c
Normal file
262
src/lv_core/lv_flex.c
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* @file lv_flex.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_flex.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_dir_t main_dir, lv_coord_t max_size, lv_coord_t * grow_unit, lv_coord_t * track_cross_size);
|
||||
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_dir_t main_dir, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t track_size, lv_coord_t grow_unit);
|
||||
static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t track_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_obj_set_flex_cont(lv_obj_t * obj, lv_flex_dir_t flex_dir)
|
||||
{
|
||||
if(obj->flex_dir != flex_dir) return;
|
||||
|
||||
obj->flex_dir = flex_dir;
|
||||
_lv_flex_refresh(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_flex_item(lv_obj_t * obj, lv_flex_place_t place)
|
||||
{
|
||||
lv_obj_set_pos(obj, place, place);
|
||||
}
|
||||
|
||||
void _lv_flex_refresh(lv_obj_t * cont)
|
||||
{
|
||||
if(cont->flex_dir == LV_FLEX_DIR_NONE) return;
|
||||
|
||||
lv_dir_t main_dir;
|
||||
switch(cont->flex_dir) {
|
||||
case LV_FLEX_DIR_ROW:
|
||||
main_dir = LV_DIR_HOR;
|
||||
break;
|
||||
case LV_FLEX_DIR_ROW_WRAP:
|
||||
main_dir = LV_DIR_HOR;
|
||||
break;
|
||||
case LV_FLEX_DIR_COLUMN:
|
||||
main_dir = LV_DIR_VER;
|
||||
break;
|
||||
case LV_FLEX_DIR_COLUMN_WRAP:
|
||||
main_dir = LV_DIR_VER;
|
||||
break;
|
||||
}
|
||||
|
||||
/*Count the grow units and free space*/
|
||||
lv_coord_t max_main_size = (main_dir == LV_DIR_HOR ? 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 * cross_pos = (main_dir == LV_DIR_HOR ? &abs_y : &abs_x);
|
||||
|
||||
lv_coord_t row_place = LV_FLEX_START;
|
||||
lv_coord_t all_track_size = 0;
|
||||
lv_coord_t gap = 0;
|
||||
uint32_t row_cnt = 0;
|
||||
lv_coord_t grow_unit;
|
||||
lv_coord_t track_size;
|
||||
lv_obj_t * track_first_item;
|
||||
lv_obj_t * next_track_first_item;
|
||||
|
||||
if(row_place != LV_FLEX_START) {
|
||||
track_first_item = _lv_ll_get_tail(&cont->child_ll);
|
||||
while(track_first_item) {
|
||||
/*Search the first item of the next row */
|
||||
next_track_first_item = find_track_end(cont, track_first_item, main_dir, max_main_size, &grow_unit, &track_size);
|
||||
all_track_size += track_size;
|
||||
row_cnt++;
|
||||
track_first_item = next_track_first_item;
|
||||
}
|
||||
|
||||
lv_coord_t max_cross_size = (main_dir == LV_DIR_HOR ? lv_obj_get_height_fit(cont) : lv_obj_get_width_fit(cont));
|
||||
place_content(row_place, max_cross_size, all_track_size,row_cnt, cross_pos, &gap);
|
||||
}
|
||||
|
||||
track_first_item = _lv_ll_get_tail(&cont->child_ll);
|
||||
while(track_first_item) {
|
||||
/*Search the first item of the next row */
|
||||
next_track_first_item = find_track_end(cont, track_first_item, main_dir, max_main_size, &grow_unit, &track_size);
|
||||
|
||||
children_repos(cont, track_first_item, next_track_first_item, main_dir, abs_x, abs_y, track_size, grow_unit);
|
||||
|
||||
track_first_item = next_track_first_item;
|
||||
*cross_pos += track_size + gap;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_dir_t main_dir, lv_coord_t max_size, lv_coord_t * grow_unit, lv_coord_t * track_cross_size)
|
||||
{
|
||||
lv_coord_t(*get_main_size)(const lv_obj_t *) = (main_dir == LV_DIR_HOR ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
lv_coord_t(*get_cross_size)(const lv_obj_t *) = (main_dir == LV_DIR_VER ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
|
||||
bool wrap;
|
||||
if(cont->flex_dir == LV_FLEX_DIR_ROW_WRAP || cont->flex_dir == LV_FLEX_DIR_COLUMN_WRAP) {
|
||||
wrap = true;
|
||||
} else {
|
||||
wrap = false;
|
||||
}
|
||||
|
||||
lv_coord_t grow_sum = 0;
|
||||
lv_coord_t used_size = 0;
|
||||
*track_cross_size = 0;
|
||||
*grow_unit = 0;
|
||||
|
||||
lv_obj_t * item = item_start;
|
||||
while(item) {
|
||||
/*Ignore non-flex items*/
|
||||
lv_coord_t main_set = (main_dir == LV_DIR_HOR ? item->x_set : item->y_set);
|
||||
if(LV_COORD_IS_FLEX(main_set) == false) {
|
||||
item = _lv_ll_get_prev(&cont->child_ll, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_coord_t main_size = (main_dir == LV_DIR_HOR ? item->w_set : item->h_set);
|
||||
if(_LV_FLEX_GET_GROW(main_size)) {
|
||||
grow_sum += _LV_FLEX_GET_GROW(main_size);
|
||||
} else {
|
||||
lv_coord_t item_size = get_main_size(item);
|
||||
if(wrap && used_size + item_size > max_size) break;
|
||||
used_size += item_size;
|
||||
}
|
||||
|
||||
*track_cross_size = LV_MATH_MAX(get_cross_size(item), *track_cross_size);
|
||||
|
||||
item = _lv_ll_get_prev(&cont->child_ll, item);
|
||||
}
|
||||
|
||||
*grow_unit = grow_sum ? (max_size - used_size) / grow_sum : 0;
|
||||
if(*grow_unit < 0) *grow_unit = 0;
|
||||
|
||||
/*Have at least one item in a row*/
|
||||
if(item && item == item_start) {
|
||||
item = _lv_ll_get_prev(&cont->child_ll, item);
|
||||
if(item) *track_cross_size = get_cross_size(item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_dir_t main_dir, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t track_size, lv_coord_t grow_unit)
|
||||
{
|
||||
lv_coord_t(*get_main_size)(const lv_obj_t *) = (main_dir == LV_DIR_HOR ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
void (*set_main_size)(lv_obj_t *, lv_coord_t) = (main_dir == LV_DIR_HOR ? lv_obj_set_width_margin : lv_obj_set_height_margin);
|
||||
lv_coord_t(*get_cross_size)(const lv_obj_t *) = (main_dir == LV_DIR_VER ? lv_obj_get_width_margin : lv_obj_get_height_margin);
|
||||
|
||||
lv_coord_t main_pos = 0;
|
||||
/*Reposition the children*/
|
||||
lv_obj_t * item = item_first; /*Just to use a shorter name*/
|
||||
while(item != item_last) {
|
||||
|
||||
/*Ignore non-flex items*/
|
||||
lv_coord_t main_set = (main_dir == LV_DIR_HOR ? item->x_set : item->y_set);
|
||||
if(LV_COORD_IS_FLEX(main_set) == false) {
|
||||
item = _lv_ll_get_prev(&cont->child_ll, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_coord_t main_size = (main_dir == LV_DIR_HOR ? item->w_set : item->h_set);
|
||||
if(_LV_FLEX_GET_GROW(main_size)) {
|
||||
lv_coord_t s = _LV_FLEX_GET_GROW(main_size) * grow_unit;
|
||||
set_main_size(item, s);
|
||||
}
|
||||
|
||||
lv_coord_t cross_pos = 0;
|
||||
lv_coord_t cross_set = (main_dir == LV_DIR_HOR ? item->y_set : item->x_set);
|
||||
switch(cross_set) {
|
||||
case LV_FLEX_CENTER:
|
||||
cross_pos = (track_size - get_cross_size(item)) / 2;
|
||||
break;
|
||||
case LV_FLEX_END:
|
||||
cross_pos = track_size - get_cross_size(item);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_coord_t diff_x;
|
||||
lv_coord_t diff_y;
|
||||
if(main_dir == LV_DIR_HOR) {
|
||||
diff_x = abs_x + main_pos - item->coords.x1;
|
||||
diff_y = abs_y + cross_pos - item->coords.y1;
|
||||
} else {
|
||||
diff_x = abs_x + cross_pos - item->coords.x1;
|
||||
diff_y = abs_y + main_pos - item->coords.y1;
|
||||
}
|
||||
|
||||
if(diff_x || diff_y) {
|
||||
item->coords.x1 += diff_x;
|
||||
item->coords.x2 += diff_x;
|
||||
item->coords.y1 += diff_y;
|
||||
item->coords.y2 += diff_y;
|
||||
_lv_obj_move_children_by(item, diff_x, diff_y);
|
||||
}
|
||||
main_pos += get_main_size(item);
|
||||
item = _lv_ll_get_prev(&cont->child_ll, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t track_cnt, lv_coord_t * start_pos, lv_coord_t * gap)
|
||||
{
|
||||
if(track_cnt <= 1) {
|
||||
switch(place) {
|
||||
case LV_FLEX_SPACE_BETWEEN:
|
||||
case LV_FLEX_SPACE_AROUND:
|
||||
case LV_FLEX_SPACE_EVENLY:
|
||||
place = LV_FLEX_CENTER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(place) {
|
||||
case LV_FLEX_CENTER:
|
||||
*start_pos += (max_size - track_size) / 2;
|
||||
break;
|
||||
case LV_FLEX_END:
|
||||
*start_pos += max_size - track_size;
|
||||
break;
|
||||
case LV_FLEX_SPACE_BETWEEN:
|
||||
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(track_cnt - 1);
|
||||
break;
|
||||
case LV_FLEX_SPACE_AROUND:
|
||||
*gap += (lv_coord_t)(max_size - track_size) / (lv_coord_t)(track_cnt);
|
||||
*start_pos += *gap / 2;
|
||||
break;
|
||||
case LV_FLEX_SPACE_EVENLY:
|
||||
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(track_cnt + 1);
|
||||
*start_pos += *gap;
|
||||
break;
|
||||
default:
|
||||
*gap = 0;
|
||||
}
|
||||
}
|
64
src/lv_core/lv_flex.h
Normal file
64
src/lv_core/lv_flex.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file lv_flex.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FLEX_H
|
||||
#define LV_FLEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_grid.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Can be set as width or height (on main axis) to grow the object in order fill the free space*/
|
||||
#define LV_FLEX_GROW(grow) (_LV_COORD_FELX(grow))
|
||||
|
||||
#define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_FLEX(v) ? LV_COORD_GET_FLEX(v) : 0)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_FLEX_START = _LV_COORD_FELX(0),
|
||||
LV_FLEX_END = _LV_COORD_FELX(1),
|
||||
LV_FLEX_CENTER = _LV_COORD_FELX(2),
|
||||
LV_FLEX_SPACE_EVENLY = _LV_COORD_FELX(3),
|
||||
LV_FLEX_SPACE_AROUND = _LV_COORD_FELX(4),
|
||||
LV_FLEX_SPACE_BETWEEN = _LV_COORD_FELX(5),
|
||||
}lv_flex_place_t;
|
||||
|
||||
typedef enum {
|
||||
LV_FLEX_DIR_NONE,
|
||||
LV_FLEX_DIR_ROW,
|
||||
LV_FLEX_DIR_ROW_WRAP,
|
||||
LV_FLEX_DIR_COLUMN,
|
||||
LV_FLEX_DIR_COLUMN_WRAP,
|
||||
} lv_flex_dir_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_obj_set_flex_cont(lv_obj_t * obj, lv_flex_dir_t flex_dir);
|
||||
void lv_obj_set_flex_item(lv_obj_t * obj, lv_flex_place_t place);
|
||||
void _lv_flex_refresh(lv_obj_t * cont);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_FLEX_H*/
|
@ -26,10 +26,8 @@ typedef struct {
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
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);
|
||||
static void calc_implicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc);
|
||||
static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc);
|
||||
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);
|
||||
static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint);
|
||||
static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t place, lv_coord_t gap, uint32_t track_num, lv_coord_t * size_array, lv_coord_t * pos_array);
|
||||
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
|
||||
@ -99,24 +97,17 @@ 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;
|
||||
|
||||
if(lv_obj_get_child(cont, NULL) == NULL) {
|
||||
_lv_memset_00(calc_out, sizeof(_lv_grid_calc_t));
|
||||
return;
|
||||
}
|
||||
// printf("calc: %d, %d\n", obj->grid->col_dsc_len, obj->grid->row_dsc_len);
|
||||
|
||||
if(cont->grid->col_dsc && cont->grid->row_dsc) {
|
||||
calc_explicit_rows(cont, calc_out);
|
||||
calc_explicit_cols(cont, calc_out);
|
||||
}
|
||||
else if(cont->grid->col_dsc && !cont->grid->row_dsc) {
|
||||
calc_explicit_cols(cont, calc_out);
|
||||
calc_implicit_rows(cont, calc_out);
|
||||
}
|
||||
else if(!cont->grid->col_dsc && cont->grid->row_dsc) {
|
||||
calc_explicit_rows(cont, calc_out);
|
||||
calc_implicit_cols(cont, calc_out);
|
||||
}
|
||||
calc_rows(cont, calc_out);
|
||||
calc_cols(cont, calc_out);
|
||||
|
||||
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(cont);
|
||||
@ -153,7 +144,7 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < obj->grid->col_dsc_len; i++) {
|
||||
if(_GRID_IS_FR(obj->grid->col_dsc[i])) return true;
|
||||
if(LV_GRID_IS_FR(obj->grid->col_dsc[i])) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -171,43 +162,12 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < obj->grid->row_dsc_len; i++) {
|
||||
if(_GRID_IS_FR(obj->grid->row_dsc[i])) return true;
|
||||
if(LV_GRID_IS_FR(obj->grid->row_dsc[i])) return true;
|
||||
}
|
||||
|
||||
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
|
||||
@ -232,7 +192,7 @@ void _lv_grid_full_refresh(lv_obj_t * cont)
|
||||
|
||||
lv_obj_t * item = lv_obj_get_child_back(cont, NULL);
|
||||
while(item) {
|
||||
if(_GRID_IS_CELL(item->x_set) && _GRID_IS_CELL(item->y_set)) {
|
||||
if(LV_COORD_IS_GRID(item->x_set) && LV_COORD_IS_GRID(item->y_set)) {
|
||||
item_repos(cont, item, &calc, &hint);
|
||||
}
|
||||
item = lv_obj_get_child_back(cont, item);
|
||||
@ -266,80 +226,46 @@ void lv_grid_item_refr_pos(lv_obj_t * item)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
|
||||
static void calc_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 fill = false;
|
||||
bool all = false;
|
||||
if(grid->col_dsc_len == 1 && _GRID_IS_FILL(grid->col_dsc[0])) fill = true;
|
||||
if(grid->col_dsc_len == 1 && _GRID_IS_REPEAT(grid->col_dsc[0])) all = true;
|
||||
|
||||
if(fill) {
|
||||
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);
|
||||
}
|
||||
if(all) {
|
||||
calc->col_num = lv_obj_count_children(cont);
|
||||
}
|
||||
else {
|
||||
calc->col_num = grid->col_dsc_len;
|
||||
}
|
||||
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(fill) {
|
||||
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;
|
||||
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 < calc->col_num; i++) {
|
||||
lv_coord_t x = grid->col_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) col_fr_cnt += LV_GRID_GET_FR(x);
|
||||
else {
|
||||
calc->w[i] = x;
|
||||
grid_w += x;
|
||||
}
|
||||
}
|
||||
/*If repeated, it's simple: every track has the "repeat size"*/
|
||||
else if(all) {
|
||||
lv_coord_t rep_w;
|
||||
if(grid->col_dsc[0] == LV_GRID_REPEAT_FIT) rep_w = lv_obj_get_width_fit(cont);
|
||||
else rep_w = _GRID_GET_REPEAT(grid->col_dsc[0]);
|
||||
|
||||
for(i = 0; i < calc->col_num; i++) {
|
||||
calc->w[i] = rep_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;
|
||||
cont_w -= grid->col_gap * (calc->col_num - 1);
|
||||
lv_coord_t free_w = cont_w - grid_w;
|
||||
|
||||
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);
|
||||
for(i = 0; i < calc->col_num; i++) {
|
||||
lv_coord_t x = grid->col_dsc[i];
|
||||
if(LV_GRID_IS_FR(x)) {
|
||||
if(auto_w) calc->w[i] = 0; /*Fr is considered zero if the cont has auto width*/
|
||||
else {
|
||||
calc->w[i] = x;
|
||||
grid_w += x;
|
||||
}
|
||||
}
|
||||
|
||||
cont_w -= grid->col_gap * (calc->col_num - 1);
|
||||
lv_coord_t free_w = cont_w - grid_w;
|
||||
|
||||
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*/
|
||||
else {
|
||||
lv_coord_t f = _GRID_GET_FR(x);
|
||||
calc->w[i] = (free_w * f) / col_fr_cnt;
|
||||
}
|
||||
lv_coord_t f = LV_GRID_GET_FR(x);
|
||||
calc->w[i] = (free_w * f) / col_fr_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void calc_explicit_rows(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;
|
||||
uint32_t i;
|
||||
@ -356,7 +282,7 @@ static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
|
||||
|
||||
for(i = 0; i < grid->row_dsc_len; i++) {
|
||||
lv_coord_t x = grid->row_dsc[i];
|
||||
if(_GRID_IS_FR(x)) row_fr_cnt += _GRID_GET_FR(x);
|
||||
if(LV_GRID_IS_FR(x)) row_fr_cnt += LV_GRID_GET_FR(x);
|
||||
else {
|
||||
calc->h[i] = x;
|
||||
grid_h += x;
|
||||
@ -368,86 +294,16 @@ static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
|
||||
|
||||
for(i = 0; i < grid->row_dsc_len; i++) {
|
||||
lv_coord_t x = grid->row_dsc[i];
|
||||
if(_GRID_IS_FR(x)) {
|
||||
if(LV_GRID_IS_FR(x)) {
|
||||
if(auto_h) calc->h[i] = 0; /*Fr is considered zero if the obj has auto height*/
|
||||
else {
|
||||
lv_coord_t f = _GRID_GET_FR(x);
|
||||
lv_coord_t f = LV_GRID_GET_FR(x);
|
||||
calc->h[i] = (free_h * f) / row_fr_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void calc_implicit_cols(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->col_num = ((child_cnt + grid->row_dsc_len - 1) / grid->row_dsc_len); /*+ grid->row_dsc_len - 1 to round up*/
|
||||
calc->w = _lv_mem_buf_get(sizeof(lv_coord_t) * (calc->col_num + 1)); /*+1 to allow some limit checks later*/
|
||||
calc->x = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num);
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child_back(cont, NULL);
|
||||
uint32_t row_i = 0;
|
||||
uint32_t col_i = 0;
|
||||
calc->w[0] = 0;
|
||||
while(child) {
|
||||
if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) {
|
||||
lv_coord_t w;
|
||||
if(_GRID_GET_CELL_FLAG(child->x_set) == LV_GRID_STRETCH) {
|
||||
lv_obj_scroll_to_x(child, 0, LV_ANIM_OFF);
|
||||
_lv_obj_calc_auto_size(child, &w, NULL);
|
||||
}
|
||||
else w = lv_obj_get_width(child);
|
||||
calc->w[col_i] = LV_MATH_MAX(calc->w[col_i], w);
|
||||
row_i++;
|
||||
if(row_i == grid->row_dsc_len) {
|
||||
row_i = 0;
|
||||
col_i++;
|
||||
calc->w[col_i] = 0;
|
||||
}
|
||||
}
|
||||
child = lv_obj_get_child_back(cont, child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 + 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);
|
||||
|
||||
lv_obj_t * child = lv_obj_get_child_back(cont, NULL);
|
||||
uint32_t col_i = 0;
|
||||
uint32_t row_i = 0;
|
||||
calc->h[0] = 0;
|
||||
while(child) {
|
||||
if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) {
|
||||
lv_coord_t h;
|
||||
if(_GRID_GET_CELL_FLAG(child->y_set) == LV_GRID_STRETCH) {
|
||||
lv_obj_scroll_to_y(child, 0, LV_ANIM_OFF);
|
||||
_lv_obj_calc_auto_size(child, NULL, &h);
|
||||
}
|
||||
else h = lv_obj_get_height(child);
|
||||
calc->h[row_i] = LV_MATH_MAX(calc->h[row_i], h);
|
||||
col_i++;
|
||||
if(col_i == calc->col_num) {
|
||||
col_i = 0;
|
||||
row_i++;
|
||||
calc->h[row_i] = 0;
|
||||
}
|
||||
}
|
||||
child = lv_obj_get_child_back(cont, child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reposition a grid item in its cell
|
||||
* @param cont a grid container object
|
||||
@ -460,60 +316,10 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
|
||||
{
|
||||
if(_lv_obj_is_grid_item(item) == false) return;
|
||||
|
||||
uint32_t col_pos;
|
||||
uint32_t col_span;
|
||||
uint32_t row_pos;
|
||||
uint32_t row_span;
|
||||
|
||||
if(cont->grid->row_dsc && cont->grid->col_dsc) {
|
||||
col_pos = _GRID_GET_CELL_POS(item->x_set);
|
||||
col_span = _GRID_GET_CELL_SPAN(item->x_set);
|
||||
row_pos = _GRID_GET_CELL_POS(item->y_set);
|
||||
row_span = _GRID_GET_CELL_SPAN(item->y_set);
|
||||
} else {
|
||||
col_span = 1;
|
||||
row_span = 1;
|
||||
|
||||
if(hint) {
|
||||
col_pos = hint->col;
|
||||
row_pos = hint->row;
|
||||
|
||||
if(cont->grid->row_dsc == NULL) {
|
||||
hint->col++;
|
||||
if(hint->col >= calc->col_num) {
|
||||
hint->col = 0;
|
||||
hint->row++;
|
||||
}
|
||||
} else {
|
||||
hint->row++;
|
||||
if(hint->row >= calc->row_num) {
|
||||
hint->row = 0;
|
||||
hint->col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*No hint -> find the child ID and calculate its col and row position */
|
||||
else {
|
||||
uint32_t child_id = 0;
|
||||
lv_obj_t * child = lv_obj_get_child_back(cont, NULL);
|
||||
|
||||
while(child) {
|
||||
if(child == item) break;
|
||||
if(_GRID_IS_CELL(child->x_set) && _GRID_IS_CELL(child->y_set)) {
|
||||
child_id++;
|
||||
}
|
||||
child = lv_obj_get_child_back(cont, child);
|
||||
}
|
||||
|
||||
if(cont->grid->row_dsc == NULL) {
|
||||
col_pos = child_id % calc->col_num;
|
||||
row_pos = child_id / calc->col_num;
|
||||
} else {
|
||||
col_pos = child_id / calc->row_num;
|
||||
row_pos = child_id % calc->row_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t col_pos = LV_GRID_GET_CELL_POS(item->x_set);
|
||||
uint32_t col_span = LV_GRID_GET_CELL_SPAN(item->x_set);
|
||||
uint32_t row_pos = LV_GRID_GET_CELL_POS(item->y_set);
|
||||
uint32_t row_span = LV_GRID_GET_CELL_SPAN(item->y_set);
|
||||
|
||||
lv_coord_t col_x1 = calc->x[col_pos];
|
||||
lv_coord_t col_x2 = calc->x[col_pos + col_span - 1] + calc->w[col_pos + col_span - 1];
|
||||
@ -523,8 +329,8 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
|
||||
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);
|
||||
uint8_t y_flag = _GRID_GET_CELL_FLAG(item->y_set);
|
||||
uint8_t x_flag = LV_GRID_GET_CELL_PLACE(item->x_set);
|
||||
uint8_t y_flag = LV_GRID_GET_CELL_PLACE(item->y_set);
|
||||
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
@ -575,15 +381,6 @@ static void item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc,
|
||||
lv_obj_invalidate(item);
|
||||
item->signal_cb(item, LV_SIGNAL_COORD_CHG, &old_coords);
|
||||
|
||||
/* If a children is a grid container and has an FR field it also needs to be updated
|
||||
* because the FR cell size will change with child size change. */
|
||||
lv_obj_t * child = lv_obj_get_child(item, NULL);
|
||||
while(child) {
|
||||
if(_lv_grid_has_fr_col(child) || _lv_grid_has_fr_row(child)) {
|
||||
_lv_grid_full_refresh(child);
|
||||
}
|
||||
child = lv_obj_get_child(item, child);
|
||||
}
|
||||
}
|
||||
bool moved = true;
|
||||
if(hint) {
|
||||
@ -613,7 +410,6 @@ static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t plac
|
||||
if(auto_size) {
|
||||
pos_array[0] = 0;
|
||||
} else {
|
||||
|
||||
/*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;
|
||||
|
@ -19,6 +19,15 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**
|
||||
* Some helper defines
|
||||
* */
|
||||
#define _LV_GRID_CELL_SHIFT 4
|
||||
#define _LV_GRID_CELL_POS_MASK ((1 << _LV_GRID_CELL_SHIFT) - 1)
|
||||
#define _LV_GRID_CELL_SPAN_MASK (_LV_GRID_CELL_POS_MASK << _LV_GRID_CELL_SHIFT)
|
||||
#define _LV_GRID_CELL_FLAG_MASK (_LV_GRID_CELL_POS_MASK << (2 * _LV_GRID_CELL_SHIFT))
|
||||
#define _LV_GRID_CELL_PLACE(b) ((b) << (_LV_GRID_CELL_SHIFT * 2))
|
||||
|
||||
#define LV_GRID_START 0
|
||||
#define LV_GRID_CENTER 1
|
||||
#define LV_GRID_END 2
|
||||
@ -27,61 +36,18 @@ extern "C" {
|
||||
#define LV_GRID_SPACE_AROUND 5
|
||||
#define LV_GRID_SPACE_BETWEEN 6
|
||||
|
||||
/**
|
||||
* Some helper defines
|
||||
* */
|
||||
#define _GRID_IS_CELL(c) ((c) >= LV_COORD_MAX ? true : false)
|
||||
#define _GRID_CELL_SHIFT 5
|
||||
#define _GRID_CELL_MAX ((1 << _GRID_CELL_SHIFT) - 1)
|
||||
#define _GRID_CELL_POS_MASK ((1 << _GRID_CELL_SHIFT) - 1)
|
||||
#define _GRID_CELL_SPAN_MASK (_GRID_CELL_POS_MASK << _GRID_CELL_SHIFT)
|
||||
#define _GRID_CELL_FLAG_MASK (_GRID_CELL_POS_MASK << (2 * _GRID_CELL_SHIFT))
|
||||
#define _GRID_CELL_FLAG(b) ((b) << (_GRID_CELL_SHIFT * 2))
|
||||
#define _GRID_CELL_AUTO _GRID_CELL_MAX
|
||||
#define _GRID_GET_CELL_POS(c) ((c) & _GRID_CELL_POS_MASK)
|
||||
#define _GRID_GET_CELL_SPAN(c) (((c) & _GRID_CELL_SPAN_MASK) >> _GRID_CELL_SHIFT)
|
||||
#define _GRID_GET_CELL_FLAG(c) ((c) >> (_GRID_CELL_SHIFT * 2) & 0x3)
|
||||
#define LV_GRID_CELL_START(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_START)))
|
||||
#define LV_GRID_CELL_END(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_END)))
|
||||
#define LV_GRID_CELL_CENTER(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_CENTER)))
|
||||
#define LV_GRID_CELL_STRETCH(pos, span) (_LV_COORD_GRID((pos) | ((span) << (_LV_GRID_CELL_SHIFT)) | _LV_GRID_CELL_PLACE(LV_GRID_STRETCH)))
|
||||
|
||||
#define _GRID_CELL_SIZE_PX 0 /* The cell size is set in pixels*/
|
||||
#define _GRID_CELL_SIZE_FR 1 /* The cell size is set in free units*/
|
||||
#define LV_GRID_GET_CELL_POS(c) ((c) & _LV_GRID_CELL_POS_MASK)
|
||||
#define LV_GRID_GET_CELL_SPAN(c) (((c) & _LV_GRID_CELL_SPAN_MASK) >> _LV_GRID_CELL_SHIFT)
|
||||
#define LV_GRID_GET_CELL_PLACE(c) ((c) >> (_LV_GRID_CELL_SHIFT * 2) & 0x7)
|
||||
|
||||
#define _GRID_FR_MAX 256
|
||||
#define _GRID_FILL_MAX 2048
|
||||
#define _GRID_REPEAT_MAX 2048
|
||||
#define _GRID_FR_START (LV_COORD_MAX)
|
||||
#define _GRID_FILL_START (_GRID_FR_START + _GRID_FR_MAX)
|
||||
#define _GRID_REPEAT_START (_GRID_FILL_START + _GRID_FILL_MAX)
|
||||
|
||||
#define LV_GRID_FR(x) (_GRID_FR_START + (x))
|
||||
#define LV_GRID_FILL(x) (_GRID_FILL_START + (x))
|
||||
#define LV_GRID_REPEAT(x) (_GRID_REPEAT_START + (x))
|
||||
#define LV_GRID_REPEAT_FIT (_GRID_REPEAT_START + _GRID_REPEAT_MAX - 1)
|
||||
|
||||
#define _GRID_IS_PX(x) ((_GRID_IS_FR(x) == false) && (_GRID_IS_AUTO(x) == false) ? true : false)
|
||||
#define _GRID_IS_FR(x) ((x) > _GRID_FR_START && (x) < _GRID_FILL_START ? true : false)
|
||||
#define _GRID_IS_FILL(x) ((x) > _GRID_FILL_START && (x) < _GRID_REPEAT_START ? true : false)
|
||||
#define _GRID_IS_REPEAT(x) ((x) > _GRID_REPEAT_START ? 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) - _GRID_FILL_START)
|
||||
#define _GRID_GET_REPEAT(x) ((x) - _GRID_REPEAT_START)
|
||||
|
||||
|
||||
/**
|
||||
* Define a grid cell with position and span.
|
||||
* Can be used like `lv_obj_set_pos(btn, LV_GRID_CELL(3,2), LV_GRID_CELL(2,1))`
|
||||
*/
|
||||
#define LV_GRID_CELL_START(pos, span) ((LV_COORD_MAX + (pos) + (span << _GRID_CELL_SHIFT)) | _GRID_CELL_FLAG(LV_GRID_START))
|
||||
#define LV_GRID_CELL_END(pos, span) ((LV_COORD_MAX + (pos) + (span << _GRID_CELL_SHIFT)) | _GRID_CELL_FLAG(LV_GRID_END))
|
||||
#define LV_GRID_CELL_CENTER(pos, span) ((LV_COORD_MAX + (pos) + (span << _GRID_CELL_SHIFT)) | _GRID_CELL_FLAG(LV_GRID_CENTER))
|
||||
#define LV_GRID_CELL_STRETCH(pos, span) ((LV_COORD_MAX + (pos) + (span << _GRID_CELL_SHIFT)) | _GRID_CELL_FLAG(LV_GRID_STRETCH))
|
||||
/**
|
||||
* Special LV_GRID_CELL position to flow the object automatically.
|
||||
* Both X (column) and Y (row) value needs to be AUTO or explicitly specified*/
|
||||
#define LV_GRID_AUTO_START LV_GRID_CELL_START(_GRID_CELL_AUTO, 0)
|
||||
#define LV_GRID_AUTO_END LV_GRID_CELL_END(_GRID_CELL_AUTO, 0)
|
||||
#define LV_GRID_AUTO_CENTER LV_GRID_CELL_CENTER(_GRID_CELL_AUTO, 0)
|
||||
#define LV_GRID_AUTO_STRETCH LV_GRID_CELL_STRETCH(_GRID_CELL_AUTO, 0)
|
||||
#define LV_GRID_FR(x) (_LV_COORD_GRID(x))
|
||||
#define LV_GRID_IS_FR(x) (LV_COORD_IS_GRID(x))
|
||||
#define LV_GRID_GET_FR(x) (LV_COORD_GET_GRID(x))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -154,19 +120,6 @@ 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);
|
||||
|
@ -1906,19 +1906,31 @@ 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) {
|
||||
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);
|
||||
bool w_new = true;
|
||||
bool h_new = true;
|
||||
if(param) {
|
||||
if(lv_area_get_width(param) == lv_obj_get_width(obj)) w_new = false;
|
||||
if(lv_area_get_height(param) == lv_obj_get_height(obj)) h_new = false;
|
||||
}
|
||||
|
||||
if(w_new || h_new) {
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(obj);
|
||||
lv_coord_t cont_h = lv_obj_get_height_fit(obj);
|
||||
lv_obj_t * child;
|
||||
_LV_LL_READ(obj->child_ll, child) {
|
||||
if(LV_COORD_IS_PCT(child->w_set) && w_new) lv_obj_set_width(child, (LV_COORD_GET_PCT(child->w_set) * cont_w) / 100);
|
||||
if(LV_COORD_IS_PCT(child->h_set) && h_new) lv_obj_set_height(child, (LV_COORD_GET_PCT(child->h_set) * cont_h) / 100);
|
||||
}
|
||||
if(obj->grid) _lv_grid_full_refresh(obj);
|
||||
if(obj->flex_dir) _lv_flex_refresh(obj);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
||||
if(param == NULL || _lv_obj_is_flex_item(param)) {
|
||||
_lv_flex_refresh(obj);
|
||||
}
|
||||
|
||||
if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) {
|
||||
lv_obj_set_size(obj, obj->w_set, obj->h_set);
|
||||
}
|
||||
@ -1933,16 +1945,6 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
||||
}
|
||||
}
|
||||
|
||||
/* If the parent has an implicit grid in a direction and this object (whose child has changed)
|
||||
* is stretched in that direction then the grid of the parent might have changed because
|
||||
* the track size of implicit grids with stretched cells is calculated from the children bounding box.*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
if(par && _lv_obj_is_grid_item(obj) &&
|
||||
((par->grid->col_dsc == NULL && _GRID_GET_CELL_FLAG(obj->x_set) == LV_GRID_STRETCH) ||
|
||||
(par->grid->row_dsc == NULL && _GRID_GET_CELL_FLAG(obj->y_set) == LV_GRID_STRETCH))) {
|
||||
_lv_grid_full_refresh(par);
|
||||
}
|
||||
|
||||
}
|
||||
else if(sign == LV_SIGNAL_SCROLL) {
|
||||
res = lv_event_send(obj, LV_EVENT_SCROLL, NULL);
|
||||
@ -1965,7 +1967,7 @@ 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_obj_get_child(obj, NULL);
|
||||
while(child) {
|
||||
if(!_GRID_IS_CELL(child->x_set) || !_GRID_IS_CELL(child->y_set)) {
|
||||
if(!LV_COORD_IS_GRID(child->x_set) || !LV_COORD_IS_GRID(child->y_set)) {
|
||||
lv_obj_set_pos(child, child->x_set, child->y_set);
|
||||
}
|
||||
child = lv_obj_get_child(obj, child);
|
||||
|
@ -19,6 +19,7 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include "lv_style.h"
|
||||
#include "lv_grid.h"
|
||||
#include "lv_flex.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
@ -255,6 +256,8 @@ typedef struct _lv_obj_t {
|
||||
|
||||
const lv_grid_t * grid;
|
||||
|
||||
uint8_t flex_dir;
|
||||
|
||||
} lv_obj_t;
|
||||
|
||||
enum {
|
||||
|
@ -54,36 +54,30 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
obj->y_set = y;
|
||||
|
||||
bool gi = _lv_obj_is_grid_item(obj);
|
||||
bool fi = _lv_obj_is_flex_item(obj);
|
||||
|
||||
/*For consistency set the size to stretched if the objects is stretched on the grid*/
|
||||
if(gi) {
|
||||
if(_GRID_GET_CELL_FLAG(obj->x_set) == LV_GRID_STRETCH) obj->w_set = LV_SIZE_STRETCH;
|
||||
if(_GRID_GET_CELL_FLAG(obj->y_set) == LV_GRID_STRETCH) obj->h_set = LV_SIZE_STRETCH;
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->x_set) == LV_GRID_STRETCH) obj->w_set = LV_SIZE_STRETCH;
|
||||
if(LV_GRID_GET_CELL_PLACE(obj->y_set) == LV_GRID_STRETCH) obj->h_set = LV_SIZE_STRETCH;
|
||||
}
|
||||
|
||||
/*If not grid item but has grid position set the position to 0*/
|
||||
/*If not grid or flex item but has grid or flex position set the position to 0*/
|
||||
if(!gi) {
|
||||
if(_GRID_IS_CELL(x)) {
|
||||
x = 0;
|
||||
}
|
||||
if(_GRID_IS_CELL(y)) {
|
||||
y = 0;
|
||||
}
|
||||
if(LV_COORD_IS_GRID(x)) x = 0;
|
||||
if(LV_COORD_IS_GRID(y)) y = 0;
|
||||
}
|
||||
|
||||
if(!fi) {
|
||||
if(LV_COORD_IS_FLEX(x)) x = 0;
|
||||
if(LV_COORD_IS_FLEX(y)) y = 0;
|
||||
}
|
||||
|
||||
/*If the object is on a grid item let the grid to position it. */
|
||||
if(gi) {
|
||||
lv_obj_t * cont = lv_obj_get_parent(obj);
|
||||
|
||||
/*If the item was moved on an implicit grid the whole grid can change so refresh the full grid.*/
|
||||
if(cont->grid->col_dsc == NULL || cont->grid->row_dsc == NULL)
|
||||
{
|
||||
_lv_grid_full_refresh(cont);
|
||||
}
|
||||
/*On explicit grids the grid itself doesn't depend on the items, so just position the item*/
|
||||
else {
|
||||
lv_grid_item_refr_pos(obj);
|
||||
}
|
||||
lv_grid_item_refr_pos(obj);
|
||||
} else if(fi) {
|
||||
_lv_flex_refresh(lv_obj_get_parent(obj));
|
||||
} else {
|
||||
_lv_obj_move_to(obj, x, y, true);
|
||||
}
|
||||
@ -124,12 +118,13 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
|
||||
|
||||
bool gi = _lv_obj_is_grid_item(obj);
|
||||
bool fi = _lv_obj_is_flex_item(obj);
|
||||
bool x_stretch = false;
|
||||
bool y_stretch = false;
|
||||
|
||||
if(gi) {
|
||||
x_stretch = _GRID_GET_CELL_FLAG(obj->x_set) == LV_GRID_STRETCH ? true : false;
|
||||
y_stretch = _GRID_GET_CELL_FLAG(obj->y_set) == LV_GRID_STRETCH ? true : false;
|
||||
x_stretch = LV_GRID_GET_CELL_PLACE(obj->x_set) == LV_GRID_STRETCH ? true : false;
|
||||
y_stretch = LV_GRID_GET_CELL_PLACE(obj->y_set) == LV_GRID_STRETCH ? true : false;
|
||||
if(x_stretch) w = LV_SIZE_STRETCH;
|
||||
if(y_stretch) h = LV_SIZE_STRETCH;
|
||||
}
|
||||
@ -137,7 +132,7 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
obj->w_set = w;
|
||||
obj->h_set = h;
|
||||
|
||||
/*If both stretched it was already managed by the grid*/
|
||||
/*If both stretched the size is managed by the grid*/
|
||||
if(x_stretch && y_stretch) return;
|
||||
|
||||
if(x_stretch) w = lv_obj_get_width(obj);
|
||||
@ -151,20 +146,20 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
if(x_auto) lv_obj_scroll_to_x(obj, 0, LV_ANIM_OFF);
|
||||
if(y_auto) lv_obj_scroll_to_y(obj, 0, LV_ANIM_OFF);
|
||||
|
||||
lv_coord_t auto_w;
|
||||
lv_coord_t auto_h;
|
||||
if(x_auto && y_auto) {
|
||||
_lv_obj_calc_auto_size(obj, &auto_w, &auto_h);
|
||||
w = auto_w;
|
||||
h = auto_h;
|
||||
}
|
||||
else if(x_auto) {
|
||||
_lv_obj_calc_auto_size(obj, &auto_w, NULL);
|
||||
w = auto_w;
|
||||
}
|
||||
else if(y_auto) {
|
||||
_lv_obj_calc_auto_size(obj, NULL, &auto_h);
|
||||
h = auto_h;
|
||||
if(x_auto && y_auto) _lv_obj_calc_auto_size(obj, &w, &h);
|
||||
else if(x_auto) _lv_obj_calc_auto_size(obj, &w, NULL);
|
||||
else if(y_auto) _lv_obj_calc_auto_size(obj, NULL, &h);
|
||||
|
||||
/*Calculate the required auto sizes*/
|
||||
bool pct_w = LV_COORD_IS_PCT(obj->w_set) ? true : false;
|
||||
bool pct_h = LV_COORD_IS_PCT(obj->h_set) ? true : false;
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
lv_coord_t cont_w = lv_obj_get_width_fit(parent);
|
||||
lv_coord_t cont_h = lv_obj_get_height_fit(parent);
|
||||
if(pct_w) w = (LV_COORD_GET_PCT(obj->w_set) * cont_w) / 100;
|
||||
if(pct_h) h = (LV_COORD_GET_PCT(obj->h_set) * cont_h) / 100;
|
||||
}
|
||||
|
||||
refr_size(obj, w, h);
|
||||
@ -523,7 +518,7 @@ lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj)
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_margin(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_height_margin(const lv_obj_t * obj)
|
||||
{
|
||||
lv_style_int_t mtop = lv_obj_get_style_margin_top(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mbottom = lv_obj_get_style_margin_bottom(obj, LV_OBJ_PART_MAIN);
|
||||
@ -537,7 +532,7 @@ lv_coord_t lv_obj_get_height_margin(lv_obj_t * obj)
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_margin(lv_obj_t * obj)
|
||||
lv_coord_t lv_obj_get_width_margin(const lv_obj_t * obj)
|
||||
{
|
||||
lv_style_int_t mleft = lv_obj_get_style_margin_left(obj, LV_OBJ_PART_MAIN);
|
||||
lv_style_int_t mright = lv_obj_get_style_margin_right(obj, LV_OBJ_PART_MAIN);
|
||||
@ -550,7 +545,7 @@ lv_coord_t lv_obj_get_width_margin(lv_obj_t * obj)
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_width(lv_obj_t * obj)
|
||||
lv_coord_t _lv_obj_get_self_width(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_point_t p = {0, LV_COORD_MIN};
|
||||
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
|
||||
@ -562,7 +557,7 @@ lv_coord_t _lv_obj_get_self_width(lv_obj_t * obj)
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_height(lv_obj_t * obj)
|
||||
lv_coord_t _lv_obj_get_self_height(struct _lv_obj_t * obj)
|
||||
{
|
||||
lv_point_t p = {LV_COORD_MIN, 0};
|
||||
lv_signal_send((lv_obj_t * )obj, LV_SIGNAL_GET_SELF_SIZE, &p);
|
||||
@ -574,7 +569,7 @@ lv_coord_t _lv_obj_get_self_height(lv_obj_t * obj)
|
||||
* @param obj pointer to an object
|
||||
* @return false: nothing happened; true: refresh happened
|
||||
*/
|
||||
bool _lv_obj_handle_self_size_chg(lv_obj_t * obj)
|
||||
bool _lv_obj_handle_self_size_chg(struct _lv_obj_t * obj)
|
||||
{
|
||||
if(obj->w_set != LV_SIZE_AUTO && obj->h_set == LV_SIZE_AUTO) return false;
|
||||
|
||||
@ -650,7 +645,7 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par
|
||||
y += pad_top + parent->coords.y1 - lv_obj_get_scroll_top(parent);
|
||||
} else {
|
||||
/*If no parent then it's screen but screen can't be on a grid*/
|
||||
if(_GRID_IS_CELL(obj->x_set) || _GRID_IS_CELL(obj->x_set)) {
|
||||
if(LV_COORD_IS_GRID(obj->x_set) || LV_COORD_IS_GRID(obj->x_set)) {
|
||||
obj->x_set = 0;
|
||||
obj->y_set = 0;
|
||||
x = 0;
|
||||
@ -722,10 +717,30 @@ 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(_GRID_IS_CELL(obj->x_set) && _GRID_IS_CELL(obj->y_set)) return true;
|
||||
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;
|
||||
if(LV_COORD_IS_GRID(obj->x_set) == false || LV_COORD_IS_GRID(obj->y_set) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an object is valid grid item or not.
|
||||
* @param obj pointer to an object to check
|
||||
* @return true: grid item; false: not grid item
|
||||
*/
|
||||
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_dir == 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;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -753,6 +768,13 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
|
||||
lv_area_t ori;
|
||||
lv_obj_get_coords(obj, &ori);
|
||||
|
||||
/* Grow size is managed by the flexbox in `LV_SIGNAL_CHILD_CHG`
|
||||
* So the real current value now.
|
||||
* w or h has `LV_FLEX_GROW(x)` value which is a very large special value
|
||||
* so it should be avoided to use such a special value as width*/
|
||||
if(_LV_FLEX_GET_GROW(obj->w_set)) w = lv_obj_get_width(obj);
|
||||
if(_LV_FLEX_GET_GROW(obj->h_set)) h = lv_obj_get_height(obj);
|
||||
|
||||
/* Set the length and height
|
||||
* Be sure the content is not scrolled in an invalid position on the new size*/
|
||||
obj->coords.y2 = obj->coords.y1 + h - 1;
|
||||
|
@ -33,11 +33,11 @@ struct _lv_obj_t;
|
||||
* @param obj pointer to an object
|
||||
* @param x new distance from the left side of the parent plus the parent's left padding or a grid cell
|
||||
* @param y new distance from the top side of the parent plus the parent's right padding or a grid cell
|
||||
* @note Zero value value means place the object is on the left padding of the parent, and not on the left edge.
|
||||
* @note A grid cell can be and explicit placement with cell position and span:
|
||||
* `LV_GRID_CELL_START/END/CENTER/STRETCH(pos, span)`
|
||||
* or "auto" to place the object on the grid in the creation order of other children
|
||||
* `LV_GRID_AUTO_START/END/CENTER/STRETCH`
|
||||
* @note Zero value value means place the object on the left/top padding of the parent, and not on the left/top edge.
|
||||
* @note For grid cells: `LV_GRID_CELL_START/END/CENTER/STRETCH(pos, span)`
|
||||
* For flex items: `LV_FLEX_POS/START/END/CENTER`
|
||||
* For percentage size: `LV_SIZE_PCT(pct)`
|
||||
* For auto size (to set size to children size): `LV_SIZE_AUTO`
|
||||
* @note to use grid placement the parent needs have a defined grid with `lv_obj_set_grid`
|
||||
*/
|
||||
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
|
||||
@ -188,7 +188,7 @@ lv_coord_t lv_obj_get_height_fit(const struct _lv_obj_t * obj);
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_height_margin(struct _lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_height_margin(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object by taking the left and right margin into account.
|
||||
@ -196,28 +196,28 @@ lv_coord_t lv_obj_get_height_margin(struct _lv_obj_t * obj);
|
||||
* @param obj pointer to an object
|
||||
* @return the height including the margins
|
||||
*/
|
||||
lv_coord_t lv_obj_get_width_margin(struct _lv_obj_t * obj);
|
||||
lv_coord_t lv_obj_get_width_margin(const struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_width(lv_obj_t * obj);
|
||||
lv_coord_t _lv_obj_get_self_width(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of the virtual content of an object
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
*/
|
||||
lv_coord_t _lv_obj_get_self_height(lv_obj_t * obj);
|
||||
lv_coord_t _lv_obj_get_self_height(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Handle if the size of the internal (virtual) content of an object has changed.
|
||||
* @param obj pointer to an object
|
||||
* @return false: nothing happened; true: refresh happened
|
||||
*/
|
||||
bool _lv_obj_handle_self_size_chg(lv_obj_t * obj);
|
||||
bool _lv_obj_handle_self_size_chg(struct _lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
|
||||
@ -252,6 +252,8 @@ void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coor
|
||||
*/
|
||||
bool _lv_obj_is_grid_item(struct _lv_obj_t * obj);
|
||||
|
||||
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -209,13 +209,33 @@ void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_COORD_PX(x) (x)
|
||||
#define LV_SIZE_AUTO (LV_COORD_MAX - 1)
|
||||
#define LV_SIZE_STRETCH (LV_COORD_MAX - 2)
|
||||
#define _LV_COORD_TYPE_SHIFT (13)
|
||||
#define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_PX (0 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_GRID (1 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_FLEX (2 << _LV_COORD_TYPE_SHIFT)
|
||||
#define _LV_COORD_TYPE_SPEC (3 << _LV_COORD_TYPE_SHIFT)
|
||||
|
||||
#define LV_COORD_IS_PX(x) (((x) < LV_COORD_MAX - 2) ? true : false)
|
||||
#define LV_COORD_IS_AUTO(x) (((x) == LV_SIZE_AUTO) ? true : false)
|
||||
#define LV_COORD_IS_PX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_PX) ? true : false)
|
||||
#define LV_COORD_IS_GRID(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_GRID) ? true : false)
|
||||
#define LV_COORD_IS_FLEX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_FLEX) ? true : false)
|
||||
#define LV_COORD_IS_SPEC(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_SPEC) ? true : false)
|
||||
|
||||
#define LV_COORD_GET_PX(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_GRID(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_FLEX(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
#define LV_COORD_GET_SPEC(x) ((x) & ~(_LV_COORD_TYPE_MASK))
|
||||
|
||||
#define _LV_COORD_GRID(x) (_LV_COORD_TYPE_GRID | (x))
|
||||
#define _LV_COORD_FELX(x) (_LV_COORD_TYPE_FLEX | (x))
|
||||
#define _LV_COORD_SPEC(x) (_LV_COORD_TYPE_SPEC | (x))
|
||||
|
||||
/*Special coordinates*/
|
||||
#define LV_COORD_PCT(x) _LV_COORD_SPEC((x))
|
||||
#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && LV_COORD_GET_SPEC(x) <= 1000) ? true : false)
|
||||
#define LV_COORD_GET_PCT(x) LV_COORD_GET_SPEC(x)
|
||||
#define LV_SIZE_AUTO _LV_COORD_SPEC(1001)
|
||||
#define LV_SIZE_STRETCH _LV_COORD_SPEC(1002)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -25,7 +25,7 @@
|
||||
*********************/
|
||||
/*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/
|
||||
#ifndef LV_MEM_ADD_JUNK
|
||||
#define LV_MEM_ADD_JUNK 1
|
||||
#define LV_MEM_ADD_JUNK 0
|
||||
#endif
|
||||
|
||||
#ifndef LV_MEM_FULL_DEFRAG_CNT
|
||||
|
@ -118,9 +118,7 @@ void lv_checkbox_set_text(lv_obj_t * cb, const char * txt)
|
||||
strcpy(ext->txt, txt);
|
||||
ext->static_txt = 0;
|
||||
|
||||
if(cb->w_set == LV_SIZE_AUTO || cb->h_set == LV_SIZE_AUTO) {
|
||||
lv_obj_set_size(cb, cb->w_set, cb->h_set);
|
||||
}
|
||||
_lv_obj_handle_self_size_chg(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,9 +136,7 @@ void lv_checkbox_set_text_static(lv_obj_t * cb, const char * txt)
|
||||
ext->txt = txt;
|
||||
ext->static_txt = 1;
|
||||
|
||||
if(cb->w_set == LV_SIZE_AUTO || cb->h_set == LV_SIZE_AUTO) {
|
||||
lv_obj_set_size(cb, cb->w_set, cb->h_set);
|
||||
}
|
||||
_lv_obj_handle_self_size_chg(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
170
src/lv_widgets/lv_linemeter.h
Normal file
170
src/lv_widgets/lv_linemeter.h
Normal file
@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @file lv_linemeter.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LINEMETER_H
|
||||
#define LV_LINEMETER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_LINEMETER != 0
|
||||
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of line meter*/
|
||||
typedef struct {
|
||||
/*No inherited ext.*/ /*Ext. of ancestor*/
|
||||
/*New data for this type */
|
||||
uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/
|
||||
uint16_t angle_ofs;
|
||||
uint16_t line_cnt; /*Count of lines */
|
||||
int32_t cur_value;
|
||||
int32_t min_value;
|
||||
int32_t max_value;
|
||||
uint8_t mirrored : 1;
|
||||
} lv_linemeter_ext_t;
|
||||
|
||||
/*Styles*/
|
||||
enum {
|
||||
LV_LINEMETER_PART_MAIN,
|
||||
_LV_LINEMETER_PART_VIRTUAL_LAST,
|
||||
_LV_LINEMETER_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST,
|
||||
};
|
||||
typedef uint8_t lv_linemeter_part_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a line meter objects
|
||||
* @param par pointer to an object, it will be the parent of the new line meter
|
||||
* @param copy pointer to a line meter object, if not NULL then the new object will be copied from
|
||||
* it
|
||||
* @return pointer to the created line meter
|
||||
*/
|
||||
lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set a new value on the line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @param value new value
|
||||
*/
|
||||
void lv_linemeter_set_value(lv_obj_t * lmeter, int32_t value);
|
||||
|
||||
/**
|
||||
* Set minimum and the maximum values of a line meter
|
||||
* @param lmeter pointer to he line meter object
|
||||
* @param min minimum value
|
||||
* @param max maximum value
|
||||
*/
|
||||
void lv_linemeter_set_range(lv_obj_t * lmeter, int32_t min, int32_t max);
|
||||
|
||||
/**
|
||||
* Set the scale settings of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @param angle angle of the scale (0..360)
|
||||
* @param line_cnt number of lines
|
||||
*/
|
||||
void lv_linemeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint16_t line_cnt);
|
||||
|
||||
/**
|
||||
* Set the set an offset for the line meter's angles to rotate it.
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @param angle angle offset (0..360), rotates clockwise
|
||||
*/
|
||||
void lv_linemeter_set_angle_offset(lv_obj_t * lmeter, uint16_t angle);
|
||||
|
||||
/**
|
||||
* Set the orientation of the meter growth, clockwise or counterclockwise (mirrored)
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @param mirror mirror setting
|
||||
*/
|
||||
void lv_linemeter_set_mirror(lv_obj_t * lmeter, bool mirror);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the value of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return the value of the line meter
|
||||
*/
|
||||
int32_t lv_linemeter_get_value(const lv_obj_t * lmeter);
|
||||
|
||||
/**
|
||||
* Get the minimum value of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return the minimum value of the line meter
|
||||
*/
|
||||
int32_t lv_linemeter_get_min_value(const lv_obj_t * lmeter);
|
||||
|
||||
/**
|
||||
* Get the maximum value of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return the maximum value of the line meter
|
||||
*/
|
||||
int32_t lv_linemeter_get_max_value(const lv_obj_t * lmeter);
|
||||
|
||||
/**
|
||||
* Get the scale number of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return number of the scale units
|
||||
*/
|
||||
uint16_t lv_linemeter_get_line_count(const lv_obj_t * lmeter);
|
||||
|
||||
/**
|
||||
* Get the scale angle of a line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return angle of the scale
|
||||
*/
|
||||
uint16_t lv_linemeter_get_scale_angle(const lv_obj_t * lmeter);
|
||||
|
||||
/**
|
||||
* Get the offset for the line meter.
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return angle offset (0..360)
|
||||
*/
|
||||
uint16_t lv_linemeter_get_angle_offset(lv_obj_t * lmeter);
|
||||
|
||||
|
||||
void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uint8_t part);
|
||||
|
||||
/**
|
||||
* get the mirror setting for the line meter
|
||||
* @param lmeter pointer to a line meter object
|
||||
* @return mirror (true or false)
|
||||
*/
|
||||
bool lv_linemeter_get_mirror(lv_obj_t * lmeter);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_LINEMETER*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_LINEMETER_H*/
|
@ -597,7 +597,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
|
||||
lv_obj_t * label = get_label(roller);
|
||||
/*Be sure the label's style is updated before processing the roller*/
|
||||
if(label) lv_signal_send(label, LV_SIGNAL_STYLE_CHG, NULL);
|
||||
lv_obj_set_width(roller, roller->w_set);
|
||||
_lv_obj_handle_self_size_chg(roller);
|
||||
refr_position(roller, false);
|
||||
}
|
||||
else if(sign == LV_SIGNAL_COORD_CHG) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user