feat(layout): add deferred layout recalculation
This commit is contained in:
@@ -11,8 +11,13 @@ static void float_btn_event_cb(lv_obj_t * float_btn, lv_event_t e)
|
|||||||
lv_snprintf(buf, sizeof(buf), "Track %d", btn_cnt);
|
lv_snprintf(buf, sizeof(buf), "Track %d", btn_cnt);
|
||||||
lv_obj_t * list_btn = lv_list_add_btn(list, LV_SYMBOL_AUDIO, buf, NULL);
|
lv_obj_t * list_btn = lv_list_add_btn(list, LV_SYMBOL_AUDIO, buf, NULL);
|
||||||
btn_cnt++;
|
btn_cnt++;
|
||||||
lv_obj_scroll_to_view(list_btn, LV_ANIM_ON);
|
|
||||||
lv_obj_move_foreground(float_btn);
|
lv_obj_move_foreground(float_btn);
|
||||||
|
|
||||||
|
/* Layouts are only recalculated later but we need to know the updated position of the new button
|
||||||
|
* to scroll to it. */
|
||||||
|
lv_obj_update_layout(list);
|
||||||
|
lv_obj_scroll_to_view(list_btn, LV_ANIM_ON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ typedef struct {
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void flex_update(lv_obj_t * cont, lv_obj_t * item);
|
static void flex_update(lv_obj_t * cont);
|
||||||
static int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t item_gap, lv_coord_t max_main_size, track_t * t);
|
static int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t item_gap, lv_coord_t max_main_size, track_t * t);
|
||||||
static void children_repos(lv_obj_t * cont, int32_t item_first_id, int32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_coord_t item_gap, track_t * t);
|
static void children_repos(lv_obj_t * cont, int32_t item_first_id, int32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_coord_t item_gap, track_t * t);
|
||||||
static void place_content(lv_flex_place_t place, lv_coord_t max_size, lv_coord_t content_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
|
static void place_content(lv_flex_place_t place, lv_coord_t max_size, lv_coord_t content_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
|
||||||
@@ -145,17 +145,15 @@ void lv_obj_set_flex_grow(struct _lv_obj_t * obj, uint8_t grow)
|
|||||||
if(f->dir == LV_FLEX_FLOW_ROW) lv_obj_set_width(obj, (LV_COORD_SET_LAYOUT(grow)));
|
if(f->dir == LV_FLEX_FLOW_ROW) lv_obj_set_width(obj, (LV_COORD_SET_LAYOUT(grow)));
|
||||||
else lv_obj_set_height(obj, (LV_COORD_SET_LAYOUT(grow)));
|
else lv_obj_set_height(obj, (LV_COORD_SET_LAYOUT(grow)));
|
||||||
|
|
||||||
lv_obj_update_layout(parent, obj);
|
lv_obj_mark_layout_as_dirty(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static void flex_update(lv_obj_t * cont, lv_obj_t * item)
|
static void flex_update(lv_obj_t * cont)
|
||||||
{
|
{
|
||||||
LV_UNUSED(item);
|
|
||||||
|
|
||||||
if(cont->spec_attr == NULL) return;
|
if(cont->spec_attr == NULL) return;
|
||||||
const lv_flex_t * f = (const lv_flex_t *)cont->spec_attr->layout_dsc;
|
const lv_flex_t * f = (const lv_flex_t *)cont->spec_attr->layout_dsc;
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,8 @@ void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_pare
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void grid_update(lv_obj_t * cont, lv_obj_t * item);
|
static void grid_update(lv_obj_t * cont);
|
||||||
static void full_refresh(lv_obj_t * cont);
|
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(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
|
||||||
static void calc_free(_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_cols(lv_obj_t * cont, _lv_grid_calc_t * c);
|
||||||
@@ -109,7 +108,7 @@ void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_place_t hor_place, uint8_t col
|
|||||||
obj->x_set = LV_COORD_SET_LAYOUT(col_pos | (col_span << CELL_SHIFT) | (hor_place << (CELL_SHIFT * 2)));
|
obj->x_set = LV_COORD_SET_LAYOUT(col_pos | (col_span << CELL_SHIFT) | (hor_place << (CELL_SHIFT * 2)));
|
||||||
obj->y_set = LV_COORD_SET_LAYOUT(row_pos | (row_span << CELL_SHIFT) | (ver_place << (CELL_SHIFT * 2)));
|
obj->y_set = LV_COORD_SET_LAYOUT(row_pos | (row_span << CELL_SHIFT) | (ver_place << (CELL_SHIFT * 2)));
|
||||||
|
|
||||||
lv_obj_update_layout(parent, obj);
|
lv_obj_mark_layout_as_dirty(parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,15 +117,14 @@ void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_place_t hor_place, uint8_t col
|
|||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static void grid_update(lv_obj_t * cont, lv_obj_t * item)
|
static void grid_update(lv_obj_t * cont)
|
||||||
{
|
{
|
||||||
if(cont->spec_attr == NULL) return;
|
if(cont->spec_attr == NULL) return;
|
||||||
if(cont->spec_attr->layout_dsc == NULL) return;
|
if(cont->spec_attr->layout_dsc == NULL) return;
|
||||||
|
|
||||||
LV_LOG_INFO("update 0x%p container, triggered by 0x%p", cont, item);
|
LV_LOG_INFO("update 0x%p container, triggered by 0x%p", cont, item);
|
||||||
|
|
||||||
if(item) item_refr(item);
|
full_refresh(cont);
|
||||||
else full_refresh(cont);
|
|
||||||
|
|
||||||
LV_TRACE_LAYOUT("finished");
|
LV_TRACE_LAYOUT("finished");
|
||||||
}
|
}
|
||||||
@@ -168,27 +166,6 @@ static void full_refresh(lv_obj_t * cont)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
if(cont->w_set == LV_SIZE_CONTENT || cont->h_set == LV_SIZE_CONTENT) {
|
|
||||||
lv_obj_set_size(cont, cont->w_set, cont->h_set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the grid cells coordinates
|
* Calculate the grid cells coordinates
|
||||||
* @param cont an object that has a grid
|
* @param cont an object that has a grid
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
||||||
lv_obj_update_layout(lv_obj_get_parent(obj), obj);
|
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,12 +351,12 @@ void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f)
|
|||||||
if(f & LV_OBJ_FLAG_HIDDEN) {
|
if(f & LV_OBJ_FLAG_HIDDEN) {
|
||||||
lv_obj_invalidate(obj);
|
lv_obj_invalidate(obj);
|
||||||
if(lv_obj_is_layout_positioned(obj)) {
|
if(lv_obj_is_layout_positioned(obj)) {
|
||||||
lv_obj_update_layout(lv_obj_get_parent(obj), obj);
|
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) {
|
||||||
lv_obj_update_layout(lv_obj_get_parent(obj), obj);
|
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,7 +933,7 @@ 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);
|
lv_obj_set_size(child, child->w_set, child->h_set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lv_obj_update_layout(obj, NULL);
|
lv_obj_mark_layout_as_dirty(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -966,7 +966,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
else if(sign == LV_SIGNAL_CHILD_CHG) {
|
||||||
lv_obj_update_layout(obj, param);
|
lv_obj_mark_layout_as_dirty(obj);
|
||||||
|
|
||||||
if(obj->w_set == LV_SIZE_CONTENT || obj->h_set == LV_SIZE_CONTENT) {
|
if(obj->w_set == LV_SIZE_CONTENT || obj->h_set == LV_SIZE_CONTENT) {
|
||||||
lv_obj_set_size(obj, obj->w_set, obj->h_set);
|
lv_obj_set_size(obj, obj->w_set, obj->h_set);
|
||||||
@@ -975,7 +975,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
|||||||
else if(sign == LV_SIGNAL_BASE_DIR_CHG) {
|
else if(sign == LV_SIGNAL_BASE_DIR_CHG) {
|
||||||
/* The layout might depend on the base dir.
|
/* The layout might depend on the base dir.
|
||||||
* E.g. the first is element is on the left or right*/
|
* E.g. the first is element is on the left or right*/
|
||||||
lv_obj_update_layout(obj, NULL);
|
lv_obj_mark_layout_as_dirty(obj);
|
||||||
}
|
}
|
||||||
else if(sign == LV_SIGNAL_SCROLL) {
|
else if(sign == LV_SIGNAL_SCROLL) {
|
||||||
res = lv_event_send(obj, LV_EVENT_SCROLL, NULL);
|
res = lv_event_send(obj, LV_EVENT_SCROLL, NULL);
|
||||||
@@ -993,7 +993,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
|
|||||||
}
|
}
|
||||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||||
/* Padding might have changed so the layout should be recalculated*/
|
/* Padding might have changed so the layout should be recalculated*/
|
||||||
lv_obj_update_layout(obj, NULL);
|
lv_obj_mark_layout_as_dirty(obj);
|
||||||
|
|
||||||
/*Reposition non grid objects on by one*/
|
/*Reposition non grid objects on by one*/
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ typedef struct _lv_obj_t{
|
|||||||
lv_coord_t h_set;
|
lv_coord_t h_set;
|
||||||
lv_obj_flag_t flags;
|
lv_obj_flag_t flags;
|
||||||
lv_state_t state;
|
lv_state_t state;
|
||||||
|
uint8_t layout_inv:1;
|
||||||
}lv_obj_t;
|
}lv_obj_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
**********************/
|
**********************/
|
||||||
static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
|
||||||
static void calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out);
|
static void calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out);
|
||||||
|
static void layout_update_core(lv_obj_t * obj);
|
||||||
|
|
||||||
void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify);
|
void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify);
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ void lv_obj_set_layout(lv_obj_t * obj, const void * layout)
|
|||||||
lv_obj_allocate_spec_attr(obj);
|
lv_obj_allocate_spec_attr(obj);
|
||||||
obj->spec_attr->layout_dsc = layout;
|
obj->spec_attr->layout_dsc = layout;
|
||||||
|
|
||||||
lv_obj_update_layout(obj, NULL);
|
lv_obj_mark_layout_as_dirty(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lv_obj_is_layout_positioned(const lv_obj_t * obj)
|
bool lv_obj_is_layout_positioned(const lv_obj_t * obj)
|
||||||
@@ -161,15 +162,35 @@ bool lv_obj_is_layout_positioned(const lv_obj_t * obj)
|
|||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_obj_update_layout(lv_obj_t * obj, lv_obj_t * item)
|
void lv_obj_mark_layout_as_dirty(lv_obj_t * obj)
|
||||||
{
|
{
|
||||||
if(obj->spec_attr == NULL) return;
|
obj->layout_inv = 1;
|
||||||
if(obj->spec_attr->layout_dsc == NULL) return;
|
|
||||||
if(obj->spec_attr->child_cnt == 0) return;
|
/*Mark the screen as dirty too to mark that there is an something to do on this screen*/
|
||||||
|
lv_obj_t * scr = lv_obj_get_screen(obj);
|
||||||
|
scr->layout_inv = 1;
|
||||||
|
|
||||||
|
/*Make the display refreshing*/
|
||||||
|
lv_disp_t * disp = lv_obj_get_disp(scr);
|
||||||
|
lv_timer_pause(disp->refr_timer, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_obj_update_layout(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
lv_obj_t * scr = lv_obj_get_screen(obj);
|
||||||
|
|
||||||
|
/*There are no dirty layouts on this screen*/
|
||||||
|
if(scr->layout_inv == 0) return;
|
||||||
|
|
||||||
|
do {
|
||||||
|
scr->layout_inv = 0;
|
||||||
|
layout_update_core(obj);
|
||||||
|
}while(scr->layout_inv); /*Repeat until there where layout invalidations*/
|
||||||
|
|
||||||
|
/* Restore the global state because other calls of this function needs this info too.
|
||||||
|
* Other calls might use different start object, but they need to know if there is dirty layout somewhere.*/
|
||||||
|
scr->layout_inv = 1;
|
||||||
|
|
||||||
const lv_layout_dsc_t * layout = obj->spec_attr->layout_dsc;
|
|
||||||
if(layout->update_cb == NULL) return;
|
|
||||||
layout->update_cb(obj, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)
|
void lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)
|
||||||
@@ -696,3 +717,21 @@ static void calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_ou
|
|||||||
*h_out = lv_obj_get_height(obj) + scroll_bottom + scroll_top;
|
*h_out = lv_obj_get_height(obj) + scroll_bottom + scroll_top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void layout_update_core(lv_obj_t * obj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
||||||
|
lv_obj_t * child = lv_obj_get_child(obj, i);
|
||||||
|
layout_update_core(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!obj->layout_inv) return;
|
||||||
|
|
||||||
|
const lv_layout_dsc_t * layout = obj->spec_attr ? obj->spec_attr->layout_dsc : NULL;
|
||||||
|
const lv_layout_update_cb_t update_cp = layout ? layout->update_cb : NULL;
|
||||||
|
if(update_cp != NULL && lv_obj_get_child_cnt(obj) > 0) {
|
||||||
|
obj->layout_inv = 0;
|
||||||
|
update_cp(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ extern "C" {
|
|||||||
**********************/
|
**********************/
|
||||||
struct _lv_obj_t;
|
struct _lv_obj_t;
|
||||||
|
|
||||||
typedef void (*lv_layout_update_cb_t)(struct _lv_obj_t * cont, struct _lv_obj_t * item);
|
typedef void (*lv_layout_update_cb_t)(struct _lv_obj_t * cont);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base of all layouts descriptor.
|
* The base of all layouts descriptor.
|
||||||
@@ -126,14 +126,17 @@ void lv_obj_set_layout(struct _lv_obj_t * obj, const void * layout);
|
|||||||
*/
|
*/
|
||||||
bool lv_obj_is_layout_positioned(const struct _lv_obj_t * obj);
|
bool lv_obj_is_layout_positioned(const struct _lv_obj_t * obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the object for layout update.
|
||||||
|
* @param obj pointer to an object whose children needs to be updated
|
||||||
|
*/
|
||||||
|
void lv_obj_mark_layout_as_dirty(struct _lv_obj_t * obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the layout of an object.
|
* Update the layout of an object.
|
||||||
* @param obj pointer to an object whose children needs to be updated
|
* @param obj pointer to an object whose children needs to be updated
|
||||||
* @param item pointer to a child object that triggered the update. Set to `NULL` is not known.
|
|
||||||
* If not `NULL` the update process can make some optimization
|
|
||||||
* to update only the required parts of the layout
|
|
||||||
*/
|
*/
|
||||||
void lv_obj_update_layout(struct _lv_obj_t * obj, struct _lv_obj_t * item);
|
void lv_obj_update_layout(struct _lv_obj_t * obj);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -199,10 +199,25 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
|||||||
lv_timer_pause(tmr, true);
|
lv_timer_pause(tmr, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*Refresh the screen's layout if required*/
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < disp_refr->screen_cnt; i++) {
|
||||||
|
lv_obj_update_layout(disp_refr->screens[i]);
|
||||||
|
disp_refr->screens[i]->layout_inv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_obj_update_layout(disp_refr->top_layer);
|
||||||
|
disp_refr->top_layer->layout_inv = 0;
|
||||||
|
|
||||||
|
lv_obj_update_layout(disp_refr->sys_layer);
|
||||||
|
disp_refr->sys_layer->layout_inv = 0;
|
||||||
|
|
||||||
|
|
||||||
/*Do nothing if there is no active screen*/
|
/*Do nothing if there is no active screen*/
|
||||||
if(disp_refr->act_scr == NULL) {
|
if(disp_refr->act_scr == NULL) {
|
||||||
disp_refr->inv_p = 0;
|
disp_refr->inv_p = 0;
|
||||||
TRACE_REFR("finished (there were no invalid areas to redraw)");
|
LV_LOG_WARN("there is no active screen");
|
||||||
|
TRACE_REFR("finished");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ typedef struct _lv_disp_t {
|
|||||||
uint32_t inv_p : 10;
|
uint32_t inv_p : 10;
|
||||||
|
|
||||||
/*Miscellaneous data*/
|
/*Miscellaneous data*/
|
||||||
uint32_t last_activity_time; /**< Last time there was activity on this display */
|
uint32_t last_activity_time; /**< Last time when there was activity on this display */
|
||||||
} lv_disp_t;
|
} lv_disp_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
Reference in New Issue
Block a user