update layouts

This commit is contained in:
Gabor Kiss-Vamosi
2021-01-03 00:12:42 +01:00
parent 98c2cdde3a
commit d027a4f00f
13 changed files with 447 additions and 669 deletions
+119 -195
View File
File diff suppressed because it is too large Load Diff
+30 -28
View File
@@ -13,16 +13,16 @@ extern "C" {
/*********************
* INCLUDES
*********************/
#include "../lv_misc/lv_area.h"
#include "lv_obj_pos.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_GROW(grow) (LV_COORD_SET_LAYOUT(grow))
#define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_FLEX(v) ? LV_COORD_GET_FLEX(v) : 0)
#define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_LAYOUT(v) ? _LV_COORD_PLAIN(v) : 0)
#define _LV_FLEX_WRAP (1 << 2)
#define _LV_FLEX_REVERSE (1 << 3)
@@ -39,32 +39,33 @@ typedef enum {
LV_FLEX_PLACE_START,
LV_FLEX_PLACE_END,
LV_FLEX_PLACE_CENTER,
LV_FLEX_PLACE_STRETCH,
LV_FLEX_PLACE_SPACE_EVENLY,
LV_FLEX_PLACE_SPACE_AROUND,
LV_FLEX_PLACE_SPACE_BETWEEN,
}lv_flex_place_t;
typedef enum {
LV_FLEX_DIR_NONE,
LV_FLEX_DIR_ROW = 0x01,
LV_FLEX_DIR_COLUMN = 0x02,
LV_FLEX_DIR_ROW_WRAP = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP,
LV_FLEX_DIR_ROW_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_REVERSE,
LV_FLEX_DIR_ROW_WRAP_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
LV_FLEX_DIR_COLUMN_WRAP = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP,
LV_FLEX_DIR_COLUMN_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_REVERSE,
LV_FLEX_DIR_COLUMN_WRAP_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
}lv_flex_dir_t;
LV_FLEX_FLOW_ROW = 0x01,
LV_FLEX_FLOW_COLUMN = 0x02,
LV_FLEX_FLOW_ROW_WRAP = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP,
LV_FLEX_FLOW_ROW_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_REVERSE,
LV_FLEX_FLOW_ROW_WRAP_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
LV_FLEX_FLOW_COLUMN_WRAP = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP,
LV_FLEX_FLOW_COLUMN_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_REVERSE,
LV_FLEX_FLOW_COLUMN_WRAP_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
}lv_flex_flow_t;
typedef struct {
lv_coord_t gap;
uint8_t dir :2;
uint8_t wrap :1;
uint8_t rev :1;
uint8_t main_place :3;
uint8_t cross_place :3;
}lv_flex_cont_t;
lv_layout_update_cb_t update_cb; /*The first element must be the update callback*/
lv_coord_t item_gap;
lv_coord_t track_gap;
uint32_t dir :2;
uint32_t wrap :1;
uint32_t rev :1;
uint32_t item_main_place :3;
uint32_t track_place :3;
uint32_t item_cross_place :3;
}lv_flex_t;
/**********************
* GLOBAL PROTOTYPES
@@ -81,7 +82,7 @@ typedef struct {
* @param obj pointer to an object
* @param flex_dir the flex direction, an element of `lv_flex_dir_t`
*/
void lv_obj_set_flex_dir(struct _lv_obj_t * obj, lv_flex_dir_t flex_dir);
void lv_obj_set_flex_dir(struct _lv_obj_t * obj, lv_flex_flow_t flex_dir);
/**
* Set how to place the items and the tracks
@@ -127,7 +128,7 @@ void lv_obj_set_flex_item_place(struct _lv_obj_t * obj, lv_flex_place_t place);
* @param obj pointer to an object
* @return the flex direction of `obj`
*/
lv_flex_dir_t lv_obj_get_flex_dir(const struct _lv_obj_t * obj);
lv_flex_flow_t lv_obj_get_flex_dir(const struct _lv_obj_t * obj);
/**
* Get the item placement of a flex container
@@ -157,12 +158,13 @@ lv_coord_t lv_obj_get_flex_gap(const struct _lv_obj_t * obj);
* @return `LV_FLEX_PLACE_NONE/START/CENTER/END`
*/
lv_flex_place_t lv_obj_get_flex_self_place(struct _lv_obj_t * obj);
/**
* Rearrange the flex items of a flex container
* @param cont pointer to a flex container object
*/
void _lv_flex_refresh(struct _lv_obj_t * cont);
/**********************
* GLOBAL VARIABLES
**********************/
extern const lv_flex_t lv_flex_center;
extern const lv_flex_t lv_flex_stacked;
extern const lv_flex_t lv_flex_even;
/**********************
* MACROS
+116 -200
View File
@@ -26,11 +26,15 @@ typedef struct {
/**********************
* STATIC PROTOTYPES
**********************/
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 * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint);
void grid_update(lv_obj_t * cont, lv_obj_t * item);
static void full_refresh(lv_obj_t * cont);
static void item_refr(lv_obj_t * item);
static void calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
static void calc_free(_lv_grid_calc_t * calc);
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c);
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c);
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, 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, bool reverse);
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
/**********************
* STATIC VARIABLES
@@ -47,6 +51,7 @@ static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
void lv_grid_init(lv_grid_t * grid)
{
_lv_memset_00(grid,sizeof(lv_grid_t));
grid->update_cb = grid_update;
grid->col_place = LV_GRID_START;
grid->row_place = LV_GRID_START;
}
@@ -72,55 +77,79 @@ void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap)
grid->row_gap = row_gap;
}
/**
* Set a grid for an object
* @param obj pointer to an object
* @param grid the grid to set
*/
void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
obj->spec_attr->grid = grid;
_lv_grid_full_refresh(obj);
}
/**
* Get the grid of an object
* @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)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr) return obj->spec_attr->grid;
return NULL;
}
void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos)
{
lv_obj_set_pos(obj, col_pos, row_pos);
}
/**
* Notify all object if a style is modified
* @param grid pointer to a grid. Only the objects with this grid will be notified
* (NULL to notify all objects with any grid)
*/
void lv_obj_report_grid_change(const lv_grid_t * grid)
{
lv_disp_t * d = lv_disp_get_next(NULL);
while(d) {
uint32_t i;
for(i = 0; i < d->screen_cnt; i++) {
report_grid_change_core(grid, d->screens[i]);
/**********************
* STATIC FUNCTIONS
**********************/
void grid_update(lv_obj_t * cont, lv_obj_t * item)
{
if(cont->spec_attr == NULL) return;
if(cont->spec_attr->layout_dsc == NULL) return;
if(item) item_refr(item);
else full_refresh(cont);
}
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
*/
static void full_refresh(lv_obj_t * cont)
{
const lv_grid_t * g = cont->spec_attr->layout_dsc;
/*Calculate the grid*/
if(g == NULL) return;
_lv_grid_calc_t c;
calc(cont, &c);
item_repos_hint_t hint;
_lv_memset_00(&hint, sizeof(hint));
/* Calculate the grids absolute x and y coordinates.
* It will be used as helper during item repositioning to avoid calculating this value for every children*/
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_PART_MAIN);
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_PART_MAIN);
hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_x(cont);
hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_y(cont);
uint32_t i;
for(i = 0; i < cont->spec_attr->child_cnt; i++) {
lv_obj_t * item = cont->spec_attr->children[i];
if(LV_COORD_IS_LAYOUT(item->x_set) && LV_COORD_IS_LAYOUT(item->y_set)) {
item_repos(item, &c, &hint);
}
d = lv_disp_get_next(d);
}
calc_free(&c);
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cont, cont->w_set, cont->h_set);
}
}
/**
* Refresh the position of a grid item
* @param item pointer to a grid item
*/
static void item_refr(lv_obj_t * item)
{
/*Calculate the grid*/
lv_obj_t * cont = lv_obj_get_parent(item);
if(cont == NULL) return;
_lv_grid_calc_t c;
calc(cont, &c);
item_repos(item, &c, NULL);
calc_free(&c);
}
/**
@@ -129,10 +158,9 @@ void lv_obj_report_grid_change(const lv_grid_t * grid)
* @param calc store the calculated cells sizes here
* @note `_lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore
*/
void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
static void calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
{
const lv_grid_t * g = lv_obj_get_grid(cont);
if(g == NULL) return;
const lv_grid_t * g = cont->spec_attr->layout_dsc;
if(g->col_dsc == NULL || g->row_dsc == NULL) return;
if(g->col_dsc_len == 0 || g->row_dsc_len == 0) return;
@@ -160,7 +188,7 @@ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
* Free the a grid calculation's data
* @param calc pointer to the calculated gtrid cell coordinates
*/
void _lv_grid_calc_free(_lv_grid_calc_t * calc)
static void calc_free(_lv_grid_calc_t * calc)
{
_lv_mem_buf_release(calc->x);
_lv_mem_buf_release(calc->y);
@@ -168,149 +196,53 @@ void _lv_grid_calc_free(_lv_grid_calc_t * calc)
_lv_mem_buf_release(calc->h);
}
/**
* Check if the object's grid columns has FR cells or not
* @param obj pointer to an object
* @return true: has FR; false: has no FR
*/
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c)
{
const lv_grid_t * g = lv_obj_get_grid(obj);
if(g->col_dsc == NULL) return false;
uint32_t i;
for(i = 0; i < g->col_dsc_len; i++) {
if(LV_GRID_IS_FR(g->col_dsc[i])) return true;
}
return false;
}
/**
* Check if the object's grid rows has FR cells or not
* @param obj pointer to an object
* @return true: has FR; false: has no FR
*/
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
{
const 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 < g->row_dsc_len; i++) {
if(LV_GRID_IS_FR(g->row_dsc[i])) return true;
}
return false;
}
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
*/
void _lv_grid_full_refresh(lv_obj_t * cont)
{
/*Calculate the grid*/
if(lv_obj_get_grid(cont) == NULL) return;
_lv_grid_calc_t calc;
_lv_grid_calc(cont, &calc);
item_repos_hint_t hint;
_lv_memset_00(&hint, sizeof(hint));
/* Calculate the grids absolute x and y coordinates.
* It will be used as helper during item repositioning to avoid calculating this value for every children*/
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_PART_MAIN);
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_PART_MAIN);
hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_x(cont);
hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_y(cont);
uint32_t i;
for(i = 0; i < cont->spec_attr->child_cnt; i++) {
lv_obj_t * item = cont->spec_attr->children[i];
if(LV_COORD_IS_GRID(item->x_set) && LV_COORD_IS_GRID(item->y_set)) {
item_repos(item, &calc, &hint);
}
}
_lv_grid_calc_free(&calc);
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cont, cont->w_set, cont->h_set);
}
}
/**
* Refresh the position of a grid item
* @param item pointer to a grid item
*/
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->spec_attr == NULL) return;
if(cont->spec_attr->grid == NULL) return;
_lv_grid_calc_t calc;
_lv_grid_calc(cont, &calc);
item_repos(item, &calc, NULL);
_lv_grid_calc_free(&calc);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
{
const lv_grid_t * grid = cont->spec_attr->grid;
const lv_grid_t * grid = cont->spec_attr->layout_dsc;
uint32_t i;
lv_coord_t cont_w = lv_obj_get_width_fit(cont);
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);
c->col_num = grid->col_dsc_len;
c->x = _lv_mem_buf_get(sizeof(lv_coord_t) * c->col_num);
c->w = _lv_mem_buf_get(sizeof(lv_coord_t) * c->col_num);
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++) {
for(i = 0; i < c->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;
c->w[i] = x;
grid_w += x;
}
}
cont_w -= grid->col_gap * (calc->col_num - 1);
cont_w -= grid->col_gap * (c->col_num - 1);
lv_coord_t free_w = cont_w - grid_w;
for(i = 0; i < calc->col_num; i++) {
for(i = 0; i < c->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*/
if(auto_w) c->w[i] = 0; /*Fr is considered zero if the cont has auto width*/
else {
lv_coord_t f = LV_GRID_GET_FR(x);
calc->w[i] = (free_w * f) / col_fr_cnt;
c->w[i] = (free_w * f) / col_fr_cnt;
}
}
}
}
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c)
{
const lv_grid_t * grid = cont->spec_attr->grid;
const lv_grid_t * grid = cont->spec_attr->layout_dsc;
uint32_t i;
calc->row_num = grid->row_dsc_len;
calc->y = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num);
calc->h = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num);
c->row_num = grid->row_dsc_len;
c->y = _lv_mem_buf_get(sizeof(lv_coord_t) * c->row_num);
c->h = _lv_mem_buf_get(sizeof(lv_coord_t) * c->row_num);
uint32_t row_fr_cnt = 0;
lv_coord_t grid_h = 0;
@@ -322,7 +254,7 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
lv_coord_t x = grid->row_dsc[i];
if(LV_GRID_IS_FR(x)) row_fr_cnt += LV_GRID_GET_FR(x);
else {
calc->h[i] = x;
c->h[i] = x;
grid_h += x;
}
}
@@ -333,10 +265,10 @@ static void calc_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(LV_GRID_IS_FR(x)) {
if(auto_h) calc->h[i] = 0; /*Fr is considered zero if the obj has auto height*/
if(auto_h) c->h[i] = 0; /*Fr is considered zero if the obj has auto height*/
else {
lv_coord_t f = LV_GRID_GET_FR(x);
calc->h[i] = (free_h * f) / row_fr_cnt;
c->h[i] = (free_h * f) / row_fr_cnt;
}
}
}
@@ -349,21 +281,21 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
* @param child_id_ext helper value if the ID of the child is know (order from the oldest) else -1
* @param grid_abs helper value, the absolute position of the grid, NULL if unknown
*/
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint)
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, item_repos_hint_t * hint)
{
if(_lv_obj_is_grid_item(item) == false) return;
if(LV_COORD_IS_LAYOUT(item->x_set) && LV_COORD_IS_LAYOUT(item->y_set)) return;
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];
lv_coord_t col_x1 = c->x[col_pos];
lv_coord_t col_x2 = c->x[col_pos + col_span - 1] + c->w[col_pos + col_span - 1];
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[row_pos + row_span - 1];
lv_coord_t row_y1 = c->y[row_pos];
lv_coord_t row_y2 = c->y[row_pos + row_span - 1] + c->h[row_pos + row_span - 1];
lv_coord_t row_h = row_y2 - row_y1;
uint8_t x_flag = LV_GRID_GET_CELL_PLACE(item->x_set);
@@ -377,47 +309,50 @@ static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_
lv_coord_t x;
lv_coord_t y;
lv_coord_t item_w = lv_obj_get_width(item);
lv_coord_t item_h = lv_obj_get_height(item);
lv_coord_t item_w = lv_area_get_width(&item->coords);
lv_coord_t item_h = lv_area_get_height(&item->coords);
lv_coord_t margin_top = lv_obj_get_style_margin_top(item, LV_PART_MAIN);
lv_coord_t margin_bottom = lv_obj_get_style_margin_bottom(item, LV_PART_MAIN);
lv_coord_t margin_left = lv_obj_get_style_margin_left(item, LV_PART_MAIN);
lv_coord_t margin_right = lv_obj_get_style_margin_right(item, LV_PART_MAIN);
if(item->w_set == LV_SIZE_LAYOUT) item->w_set = item_w;
if(item->h_set == LV_SIZE_LAYOUT) item->h_set = item_h;
switch(x_flag) {
default:
case LV_GRID_START:
x = calc->x[col_pos] + margin_left;
x = c->x[col_pos] + margin_left;
break;
case LV_GRID_STRETCH:
x = calc->x[col_pos] + margin_left;
x = c->x[col_pos] + margin_left;
item_w = col_w - margin_left - margin_right;
item->w_set = LV_SIZE_STRETCH;
item->w_set = LV_SIZE_LAYOUT;
break;
case LV_GRID_CENTER:
x = calc->x[col_pos] + (col_w - (item_w + margin_left - margin_right)) / 2;
x = c->x[col_pos] + (col_w - (item_w + margin_left - margin_right)) / 2;
break;
case LV_GRID_END:
x = calc->x[col_pos] + col_w - lv_obj_get_width(item) - margin_right;
x = c->x[col_pos] + col_w - lv_obj_get_width(item) - margin_right;
break;
}
switch(y_flag) {
default:
case LV_GRID_START:
y = calc->y[row_pos] + margin_top;
y = c->y[row_pos] + margin_top;
break;
case LV_GRID_STRETCH:
y = calc->y[row_pos] + margin_top;
y = c->y[row_pos] + margin_top;
item_h = row_h - margin_top - margin_bottom;
item->h_set = LV_SIZE_STRETCH;
item->h_set = LV_SIZE_LAYOUT;
break;
case LV_GRID_CENTER:
y = calc->y[row_pos] + (row_h - (item_h + margin_top + margin_bottom)) / 2;
y = c->y[row_pos] + (row_h - (item_h + margin_top + margin_bottom)) / 2;
break;
case LV_GRID_END:
y = calc->y[row_pos] + row_h - lv_obj_get_height(item) - margin_bottom;
y = c->y[row_pos] + row_h - lv_obj_get_height(item) - margin_bottom;
break;
}
@@ -516,22 +451,3 @@ static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t plac
/*Return the full size of the grid*/
return total_gird_size;
}
/**
* Refresh the grid of all children of an object. (Called recursively)
* @param grid refresh objects only with this grid.
* @param obj pointer to an object
*/
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj)
{
if(obj->spec_attr) {
if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj);
}
uint32_t i;
for(i = 0; i < obj->spec_attr->child_cnt; i++) {
report_grid_change_core(grid, obj->spec_attr->children[i]);
}
}
+5 -21
View File
@@ -13,7 +13,7 @@ extern "C" {
/*********************
* INCLUDES
*********************/
#include "../lv_misc/lv_area.h"
#include "lv_obj_pos.h"
/*********************
* DEFINES
@@ -45,9 +45,9 @@ extern "C" {
#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 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))
#define LV_GRID_FR(x) (LV_COORD_SET_LAYOUT(x))
#define LV_GRID_IS_FR(x) (LV_COORD_IS_LAYOUT(x))
#define LV_GRID_GET_FR(x) (_LV_COORD_PLAIN(x))
/**********************
* TYPEDEFS
@@ -57,6 +57,7 @@ extern "C" {
struct _lv_obj_t;
typedef struct {
lv_layout_update_cb_t update_cb; /*The first element must be the update callback*/
const lv_coord_t * col_dsc;
const lv_coord_t * row_dsc;
uint8_t col_dsc_len;
@@ -90,20 +91,6 @@ void lv_grid_set_place(lv_grid_t * grid, uint8_t col_place, uint8_t row_place);
void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap);
/**
* Set a grid for an object
* @param obj pointer to an object
* @param grid the grid to set
*/
void lv_obj_set_grid(struct _lv_obj_t * obj, const lv_grid_t * grid);
/**
* Get the grid of an object
* @param obj pointer to an object
* @return the grid, NULL if no grid
*/
const lv_grid_t * lv_obj_get_grid(struct _lv_obj_t * obj);
void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos);
/**
@@ -113,9 +100,6 @@ void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t
*/
void lv_obj_report_grid_change(const lv_grid_t * grid);
void _lv_grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
void _lv_grid_calc_free(_lv_grid_calc_t * calc);
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
+7 -12
View File
@@ -1474,7 +1474,7 @@ static void lv_obj_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t
obj->flags |= LV_OBJ_FLAG_SCROLLABLE;
obj->flags |= LV_OBJ_FLAG_SCROLL_ELASTIC;
obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM;
obj->flags |= LV_OBJ_FLAG_FOCUS_SCROLL;
obj->flags |= LV_OBJ_FLAG_SCROLL_ON_FOCUS;
if(parent) obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE;
obj->style_list.cache_state = LV_OBJ_STYLE_CACHE_STATE_INVALID;
@@ -1747,7 +1747,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
else if(sign == LV_SIGNAL_FOCUS) {
lv_obj_t * parent = lv_obj_get_parent(obj);
lv_obj_t * child = obj;
while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_FOCUS_SCROLL)) {
while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_SCROLL_ON_FOCUS)) {
lv_obj_scroll_to_view(child, LV_ANIM_ON);
child = parent;
parent = lv_obj_get_parent(parent);
@@ -1805,14 +1805,11 @@ 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(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);
lv_obj_update_layout(obj, NULL);
}
}
else if(sign == LV_SIGNAL_CHILD_CHG) {
if(param == NULL || _lv_obj_is_flex_item(param)) {
_lv_flex_refresh(obj);
}
lv_obj_update_layout(obj, param);
if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(obj, obj->w_set, obj->h_set);
@@ -1835,11 +1832,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
*s = LV_MATH_MAX(*s, d);
}
else if(sign == LV_SIGNAL_STYLE_CHG) {
if(_lv_obj_is_grid_item(obj)) lv_grid_item_refr_pos(obj);
if(lv_obj_get_grid(obj)) _lv_grid_full_refresh(obj);
if(_lv_obj_is_flex_item(obj)) _lv_flex_refresh(lv_obj_get_parent(obj));
if(lv_obj_get_flex_dir(obj)) _lv_flex_refresh(obj);
/* Padding might have changed so the layout should be recalculated
* If margin has also changed the parent's layout also needs to be updated but it's done in CHILD_CHG signal*/
lv_obj_update_layout(obj, NULL);
/*Reposition non grid objects on by one*/
uint32_t i;
+2 -4
View File
@@ -181,7 +181,7 @@ enum {
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 11),
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 12),
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 13),
LV_OBJ_FLAG_FOCUS_SCROLL = (1 << 14), /** Automatically scroll the focused object's ancestors to make the focused object visible*/
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1 << 14), /** Automatically scroll the focused object's ancestors to make the focused object visible*/
LV_OBJ_FLAG_ADV_HITTEST = (1 << 15),
};
typedef uint16_t lv_obj_flag_t;
@@ -192,7 +192,6 @@ typedef uint16_t lv_obj_flag_t;
#include "lv_obj_style.h"
#include "lv_obj_draw.h"
typedef struct {
struct _lv_obj_t ** children; /**< Store the pointer of the children.*/
uint32_t child_cnt;
@@ -200,11 +199,10 @@ typedef struct {
void * group_p;
#endif
const lv_grid_t * grid;
const void * layout_dsc;
lv_event_cb_t event_cb; /**< Event callback function */
lv_flex_cont_t flex_cont;
lv_point_t scroll; /**< The current X/Y scroll offset*/
lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */
+49 -99
View File
@@ -16,6 +16,9 @@
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_layout_update_cb_t update_cb;
}lv_layout_base_t;
/**********************
* STATIC PROTOTYPES
@@ -34,6 +37,24 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
* GLOBAL FUNCTIONS
**********************/
bool lv_obj_is_layout_positioned(const lv_obj_t * obj)
{
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent == NULL) return false;
if(parent->spec_attr && parent->spec_attr->layout_dsc) return true;
else return false;
}
void lv_obj_update_layout(lv_obj_t * cont, lv_obj_t * item)
{
if(cont->spec_attr == NULL) return;
if(cont->spec_attr->layout_dsc == NULL) return;
const lv_layout_base_t * layout = cont->spec_attr->layout_dsc;
if(layout->update_cb == NULL) return;
layout->update_cb(cont, item);
}
/**
* Set relative the position of an object (relative to the parent)
* @param obj pointer to an object
@@ -50,37 +71,15 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(lv_obj_is_layout_positioned(obj)) {
LV_LOG_WARN("Can't set position because the position is set by a layout");
return;
}
obj->x_set = x;
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(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 or flex item but has grid or flex position set the position to 0*/
if(!gi) {
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_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);
}
_lv_obj_move_to(obj, x, y, true);
}
/**
@@ -117,33 +116,12 @@ 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;
/*Use `LV_SIZE_STRETCH` value if the layout changes the size of the object*/
if(gi) {
if(LV_GRID_GET_CELL_PLACE(obj->x_set)) x_stretch = true;
if(LV_GRID_GET_CELL_PLACE(obj->y_set)) y_stretch = true;
}
if(fi) {
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_ROW && LV_COORD_GET_FLEX(obj->y_set) == LV_FLEX_PLACE_STRETCH) y_stretch = true;
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_COLUMN && LV_COORD_GET_FLEX(obj->x_set) == LV_FLEX_PLACE_STRETCH) x_stretch = true;
}
if(obj->w_set == LV_SIZE_LAYOUT && obj->h_set == LV_SIZE_LAYOUT) return;
if(x_stretch) w = LV_SIZE_STRETCH;
if(y_stretch) h = LV_SIZE_STRETCH;
obj->w_set = w;
obj->h_set = h;
/*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);
if(y_stretch) h = lv_obj_get_height(obj);
if(obj->w_set == LV_SIZE_LAYOUT) w = lv_obj_get_width(obj);
if(obj->h_set == LV_SIZE_LAYOUT) h = lv_obj_get_height(obj);
/*Calculate the required auto sizes*/
bool x_auto = obj->w_set == LV_SIZE_AUTO ? true : false;
@@ -163,10 +141,10 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
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;
lv_coord_t parent_w = lv_obj_get_width_fit(parent);
lv_coord_t parent_h = lv_obj_get_height_fit(parent);
if(pct_w) w = (LV_COORD_GET_PCT(obj->w_set) * parent_w) / 100;
if(pct_h) h = (LV_COORD_GET_PCT(obj->h_set) * parent_h) / 100;
}
refr_size(obj, w, h);
@@ -250,6 +228,21 @@ void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h)
lv_obj_set_height(obj, h - mtop - mbottom);
}
/**
* Set a layout for an object
* @param obj pointer to an object
* @param layout pointer to a layout descriptor to set
*/
void lv_obj_set_layout(lv_obj_t * obj, const void * layout)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->layout_dsc = layout;
lv_obj_update_layout(obj, NULL);
}
/**
* Align an object to an other object.
* @param obj pointer to an object to align
@@ -625,14 +618,6 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par
x += pad_left + parent->coords.x1 - lv_obj_get_scroll_x(parent);
y += pad_top + parent->coords.y1 - lv_obj_get_scroll_y(parent);
} else {
/*If no parent then it's screen but screen can't be on a grid*/
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;
y = 0;
}
}
/*Calculate and set the movement*/
@@ -690,41 +675,6 @@ void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_di
}
}
/**
* 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_grid_item(lv_obj_t * obj)
{
lv_obj_t * cont = lv_obj_get_parent(obj);
if(cont == NULL) return false;
const lv_grid_t * g = lv_obj_get_grid(cont);
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;
}
/**
* 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(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;
}
/**********************
* STATIC FUNCTIONS
**********************/
+9 -9
View File
@@ -24,10 +24,19 @@ extern "C" {
**********************/
struct _lv_obj_t;
typedef void (*lv_layout_update_cb_t)(struct _lv_obj_t * cont, struct _lv_obj_t * item);
typedef union {
uint32_t num;
const void * ptr;
}lv_layout_data_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_obj_update_layout(struct _lv_obj_t * cont, struct _lv_obj_t * item);
/**
* Set relative the position of an object (relative to the parent)
* @param obj pointer to an object
@@ -245,15 +254,6 @@ void _lv_obj_move_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool no
*/
void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);
/**
* 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_grid_item(struct _lv_obj_t * obj);
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj);
/**********************
* MACROS
**********************/
+34 -22
View File
@@ -47,7 +47,7 @@ typedef enum {
static void report_style_change_core(void * style, lv_obj_t * obj);
static void refresh_children_style(lv_obj_t * obj);
#if LV_USE_ANIMATION
static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit);
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit);
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v);
static void trans_anim_start_cb(lv_anim_t * a);
static void trans_anim_ready_cb(lv_anim_t * a);
@@ -78,14 +78,7 @@ void _lv_obj_style_init(void)
_lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(lv_style_trans_t));
}
/**
* Add a new style to the style list of an object.
* @param obj pointer to an object
* @param part the part of the object which style property should be set.
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
* @param style pointer to a style to add (Only its pointer will be saved)
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
void lv_obj_add_style_no_refresh(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
if(style == NULL) return;
@@ -117,6 +110,18 @@ void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_
obj->style_list.styles[i].part = part;
obj->style_list.styles[i].state = state;
}
/**
* Add a new style to the style list of an object.
* @param obj pointer to an object
* @param part the part of the object which style property should be set.
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
* @param style pointer to a style to add (Only its pointer will be saved)
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
lv_obj_add_style_no_refresh(obj, part, state, style);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
@@ -160,6 +165,17 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
void lv_obj_remove_all_styles_no_refresh(lv_obj_t * obj)
{
#if LV_USE_ANIMATION
trans_del(obj, 0xFF, 0xFF, NULL);
#endif
lv_mem_free(obj->style_list.styles);
obj->style_list.styles = NULL;
obj->style_list.style_cnt = 0;
}
/**
* Reset a style to the default (empty) state.
* Release all used memories and cancel pending related transitions.
@@ -170,14 +186,7 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style
*/
void lv_obj_remove_all_styles(lv_obj_t * obj)
{
#if LV_USE_ANIMATION
trans_del(obj, 0xFF, 0xFF, NULL);
#endif
lv_mem_free(obj->style_list.styles);
obj->style_list.styles = NULL;
obj->style_list.style_cnt = 0;
lv_obj_remove_all_styles_no_refresh(obj);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
@@ -800,8 +809,8 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
else list->cache_img_recolor_opa_zero = 0;
}
if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_CONTENT_SRC) {
if(get_prop_core(obj, part, LV_STYLE_CONTENT_SRC, &v) == false) v.num = 0;
if(v.num == 0) list->cache_content_src_zero = 1;
if(get_prop_core(obj, part, LV_STYLE_CONTENT_SRC, &v) == false) v.ptr = NULL;
if(v.ptr == NULL) list->cache_content_src_zero = 1;
else list->cache_content_src_zero = 0;
}
if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_COLOR_FILTER_CB || prop == LV_STYLE_COLOR_FILTER_OPA) {
@@ -847,7 +856,7 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
{
lv_obj_style_list_t * list = &obj->style_list;
const lv_obj_style_list_t * list = &obj->style_list;
if(part != LV_PART_MAIN) return CACHE_NEED_CHECK;
if(obj->state != list->cache_state) return CACHE_NEED_CHECK;
if(obj->style_list.skip_trans) return CACHE_NEED_CHECK;
@@ -941,7 +950,7 @@ static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t
else return CACHE_NEED_CHECK;
break;
case LV_STYLE_CONTENT_SRC:
if(list->cache_shadow_width_zero ) return CACHE_ZERO;
if(list->cache_content_src_zero ) return CACHE_ZERO;
else return CACHE_NEED_CHECK;
break;
case LV_STYLE_COLOR_FILTER_CB:
@@ -1028,10 +1037,11 @@ static void refresh_children_style(lv_obj_t * obj)
* @param prop a property or 0xFF to remove all properties
* @param tr_limit delete transitions only "older" then this. `NULL` is not used
*/
static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit)
static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit)
{
lv_style_trans_t * tr;
lv_style_trans_t * tr_prev;
bool removed = false;
tr = _lv_ll_get_tail(&LV_GC_ROOT(_lv_obj_style_trans_ll));
while(tr != NULL) {
if(tr == tr_limit) break;
@@ -1049,12 +1059,14 @@ static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_sty
lv_anim_del(tr, NULL);
_lv_ll_remove(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
lv_mem_free(tr);
removed = true;
}
}
}
tr = tr_prev;
}
return removed;
}
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v)
+15 -20
View File
@@ -224,31 +224,26 @@ void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align
#define _LV_COORD_TYPE_SHIFT (13)
#define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_PLAIN(x) ((x) & (~_LV_COORD_TYPE_MASK)) /*Remove type specifiers*/
#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_TYPE_SPEC (1 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_TYPE_LAYOUT (2 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_TYPE_RESERVED (3 << _LV_COORD_TYPE_SHIFT)
#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_IS_PX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_PX) ? true : false)
#define LV_COORD_IS_SPEC(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_SPEC) ? true : false)
#define LV_COORD_IS_LAYOUT(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_LAYOUT) ? 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))
#define LV_COORD_SET_SPEC(x) ((x) | _LV_COORD_TYPE_SPEC)
#define LV_COORD_SET_LAYOUT(x) ((x) | _LV_COORD_TYPE_LAYOUT)
/*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)
#define LV_COORD_PCT(x) _LV_COORD_SPEC(x)
#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && _LV_COORD_PLAIN(x) <= 1000) ? true : false)
#define LV_COORD_GET_PCT(x) _LV_COORD_PLAIN(x)
#define LV_SIZE_AUTO LV_COORD_SET_SPEC(1001)
#define LV_SIZE_LAYOUT LV_COORD_SET_SPEC(1002) /*The size is managed by the layout therefore `lv_obj_set_width/height/size()` can't change is*/
#ifdef __cplusplus
} /* extern "C" */
+1 -1
View File
@@ -5,7 +5,7 @@
* It's important because the virtual functions should be called from the level of the constructor.
*/
#define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \
void * _original_class_p = inst->class_p; \
const void * _original_class_p = inst->class_p; \
obj->class_p = (void*)&classname;
/**
+3 -1
View File
@@ -60,10 +60,12 @@ lv_theme_t * lv_theme_get_act(void)
*/
void lv_theme_apply(lv_obj_t * obj)
{
lv_obj_remove_all_styles(obj);
lv_obj_remove_all_styles_no_refresh(obj);
/*Apply the theme including the base theme(s)*/
apply_theme(act_theme, obj);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
}
/**
+57 -57
View File
@@ -595,106 +595,106 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
LV_UNUSED(th);
if(lv_obj_get_parent(obj) == NULL) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
return;
}
if(lv_obj_check_type(obj, &lv_obj)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
}
#if LV_USE_BTN
else if(lv_obj_check_type(obj, &lv_btn)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn_color);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->btn_color_checked);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn_color);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->btn_color_checked);
}
#endif
#if LV_USE_BAR
else if(lv_obj_check_type(obj, &lv_bar)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
}
#endif
#if LV_USE_SLIDER
else if(lv_obj_check_type(obj, &lv_slider)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal);
}
#endif
#if LV_USE_CHECKBOX
else if(lv_obj_check_type(obj, &lv_checkbox)) {
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed);
}
#endif
#if LV_USE_SWITCH
else if(lv_obj_check_type(obj, &lv_switch)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative);
}
#endif
#if LV_USE_SWITCH
else if(lv_obj_check_type(obj, &lv_chart)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->chart_bg);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->chart_bg);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style_no_refresh(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
}
#endif
#if LV_USE_ROLLER
else if(lv_obj_check_type(obj, &lv_roller)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
// lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
// lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
// lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
// lv_obj_add_style(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
// lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
// lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
// lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
// lv_obj_add_style_no_refresh(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
}
#endif
#if LV_USE_DROPDOWN
else if(lv_obj_check_type(obj, &lv_dropdown)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
}
else if(lv_obj_check_type(obj, &lv_dropdown_list)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_PRESSED, &styles->bg_color_gray);
lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_PRESSED, &styles->bg_color_gray);
}
#endif