1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

imporve grid performance

This commit is contained in:
Gabor Kiss-Vamosi 2020-09-08 09:56:56 +02:00
parent 10e0727015
commit 8b969fab61
15 changed files with 499 additions and 1049 deletions

View File

@ -1,8 +1,13 @@
CSRCS += lv_grid.c CSRCS += lv_grid.c
CSRCS += lv_group.c CSRCS += lv_group.c
CSRCS += lv_indev.c CSRCS += lv_indev.c
CSRCS += lv_indev_scroll.c
CSRCS += lv_disp.c CSRCS += lv_disp.c
CSRCS += lv_obj.c CSRCS += lv_obj.c
CSRCS += lv_obj_pos.c
CSRCS += lv_obj_style.c
CSRCS += lv_obj_draw.c
CSRCS += lv_obj_scroll.c
CSRCS += lv_refr.c CSRCS += lv_refr.c
CSRCS += lv_style.c CSRCS += lv_style.c

View File

@ -17,6 +17,11 @@
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct {
uint32_t col;
uint32_t row;
lv_point_t grid_abs;
}item_repos_hint_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
@ -25,6 +30,7 @@ static void calc_explicit_cols(lv_obj_t * cont, _lv_grid_calc_t * calc);
static void calc_explicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc); 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_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_implicit_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 VARIABLES * STATIC VARIABLES
@ -42,36 +48,47 @@ static bool row_dsc_buf_used;
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
void grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc) /**
* Calculate the grid cells coordinates
* @param obj an object that has a 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 * obj, _lv_grid_calc_t * calc_out)
{ {
if(obj->grid == NULL) return; if(obj->grid == NULL) return;
// printf("calc: %d, %d\n", obj->grid->col_dsc_len, obj->grid->row_dsc_len);
// static uint32_t cnt = 0;
// cnt++;
// printf("calc: %d (size: %d)\n", cnt, obj->grid->col_dsc_len);
if(obj->grid->col_dsc && obj->grid->row_dsc) { if(obj->grid->col_dsc && obj->grid->row_dsc) {
calc_explicit_rows(obj, calc); calc_explicit_rows(obj, calc_out);
calc_explicit_cols(obj, calc); calc_explicit_cols(obj, calc_out);
} }
else if(obj->grid->col_dsc && !obj->grid->row_dsc) { else if(obj->grid->col_dsc && !obj->grid->row_dsc) {
calc_explicit_cols(obj, calc); calc_explicit_cols(obj, calc_out);
calc_implicit_rows(obj, calc); calc_implicit_rows(obj, calc_out);
} }
else if(!obj->grid->col_dsc && obj->grid->row_dsc) { else if(!obj->grid->col_dsc && obj->grid->row_dsc) {
calc_implicit_cols(obj, calc); calc_implicit_cols(obj, calc_out);
calc_explicit_rows(obj, calc); calc_explicit_rows(obj, calc_out);
} }
} }
void grid_calc_free(_lv_grid_calc_t * calc) /**
* 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)
{ {
_lv_mem_buf_release(calc->col_dsc); _lv_mem_buf_release(calc->col_dsc);
_lv_mem_buf_release(calc->row_dsc); _lv_mem_buf_release(calc->row_dsc);
} }
/**
* 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) bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
{ {
if(obj->grid == NULL) return false; if(obj->grid == NULL) return false;
@ -85,6 +102,11 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
return false; 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) bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
{ {
if(obj->grid == NULL) return false; if(obj->grid == NULL) return false;
@ -98,164 +120,58 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
return false; return false;
} }
/**
* Refresh the all grid item on a container
static void _grid_item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, uint32_t * child_id_ext, lv_point_t * grid_abs) * @param cont pointer to a grid container object
{ */
if(_lv_obj_is_grid_item(item) == false) return; void _lv_grid_full_refresh(lv_obj_t * cont)
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;
uint32_t child_id = 0;
if(child_id_ext) child_id = *child_id_ext;
else {
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 % cont->grid->col_dsc_len;
row_pos = child_id / cont->grid->col_dsc_len;
} else {
col_pos = child_id / cont->grid->row_dsc_len;
row_pos = child_id % cont->grid->row_dsc_len;
}
}
lv_coord_t col_w = calc->col_dsc[col_pos + col_span] - calc->col_dsc[col_pos];
lv_coord_t row_h = calc->row_dsc[row_pos + row_span] - calc->row_dsc[row_pos];
uint8_t x_flag = _GRID_GET_CELL_FLAG(item->x_set);
uint8_t y_flag = _GRID_GET_CELL_FLAG(item->y_set);
lv_coord_t x;
lv_coord_t y;
lv_coord_t w = lv_obj_get_width(item);
lv_coord_t h = lv_obj_get_height(item);
switch(x_flag) {
case LV_GRID_START:
x = calc->col_dsc[col_pos];
break;
case LV_GRID_STRETCH:
x = calc->col_dsc[col_pos];
w = col_w;
item->w_set = LV_SIZE_STRETCH;
break;
case LV_GRID_CENTER:
x = calc->col_dsc[col_pos] + (col_w - w) / 2;
break;
case LV_GRID_END:
x = calc->col_dsc[col_pos + 1] - lv_obj_get_width(item);
break;
}
switch(y_flag) {
case LV_GRID_START:
y = calc->row_dsc[row_pos];
break;
case LV_GRID_STRETCH:
y = calc->row_dsc[row_pos];
item->h_set = LV_SIZE_STRETCH;
h = row_h;
break;
case LV_GRID_CENTER:
y = calc->row_dsc[row_pos] + (row_h - h) / 2;
break;
case LV_GRID_END:
y = calc->row_dsc[row_pos + 1] - lv_obj_get_height(item);
break;
}
/*Set a new size if required*/
if(lv_obj_get_width(item) != w || lv_obj_get_height(item) != h) {
lv_area_t old_coords;
lv_area_copy(&old_coords, &item->coords);
lv_obj_invalidate(item);
lv_area_set_width(&item->coords, w);
lv_area_set_height(&item->coords, h);
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_refr(child);
}
child = lv_obj_get_child(item, child);
}
}
bool moved = true;
if(grid_abs) {
if(grid_abs->x + x == item->coords.x1 && grid_abs->y + y == item->coords.y1) moved = false;
}
if(moved) _lv_obj_move_to(item, x, y, false);
}
void lv_grid_full_refr(lv_obj_t * cont)
{ {
/*Calculate the grid*/ /*Calculate the grid*/
if(cont->grid == NULL) return; if(cont->grid == NULL) return;
_lv_grid_calc_t calc; _lv_grid_calc_t calc;
grid_calc(cont, &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. /* 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*/ * It will be used as helper during item repositioning to avoid calculating this value for every children*/
lv_point_t grid_abs;
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN); lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_OBJ_PART_MAIN);
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN); lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_OBJ_PART_MAIN);
grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_left(cont); hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_left(cont);
grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_top(cont); hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_top(cont);
uint32_t child_id = 0;
lv_obj_t * item = lv_obj_get_child_back(cont, NULL); lv_obj_t * item = lv_obj_get_child_back(cont, NULL);
while(item) { while(item) {
if(_GRID_IS_CELL(item->x_set) && _GRID_IS_CELL(item->y_set)) { if(_GRID_IS_CELL(item->x_set) && _GRID_IS_CELL(item->y_set)) {
_grid_item_repos(cont, item, &calc, &child_id, &grid_abs); item_repos(cont, item, &calc, &hint);
child_id++;
} }
item = lv_obj_get_child_back(cont, item); item = lv_obj_get_child_back(cont, item);
} }
grid_calc_free(&calc); _lv_grid_calc_free(&calc);
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) { if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cont, cont->w_set, cont->h_set); 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) void lv_grid_item_refr_pos(lv_obj_t * item)
{ {
/*Calculate the grid*/ /*Calculate the grid*/
lv_obj_t * cont = lv_obj_get_parent(item); lv_obj_t * cont = lv_obj_get_parent(item);
if(cont == NULL) return;
if(cont->grid == NULL) return; if(cont->grid == NULL) return;
_lv_grid_calc_t calc; _lv_grid_calc_t calc;
grid_calc(cont, &calc); _lv_grid_calc(cont, &calc);
_grid_item_repos(cont, item, &calc, NULL, NULL); item_repos(cont, item, &calc, NULL);
grid_calc_free(&calc); _lv_grid_calc_free(&calc);
} }
/********************** /**********************
@ -479,3 +395,143 @@ static void calc_implicit_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
if(row_dsc_buf_used && row_dsc_buf_mine) row_dsc_buf_used = false; if(row_dsc_buf_used && row_dsc_buf_mine) row_dsc_buf_used = false;
else _lv_mem_buf_release(rows_h); else _lv_mem_buf_release(rows_h);
} }
/**
* Reposition a grid item in its cell
* @param cont a grid container object
* @param item a grid item to reposition
* @param calc the calculated grid of `cont`
* @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 * cont, lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint)
{
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 >= cont->grid->col_dsc_len) {
hint->col = 0;
hint->row++;
}
} else {
if(hint->row >= cont->grid->row_dsc_len) {
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 % cont->grid->col_dsc_len;
row_pos = child_id / cont->grid->col_dsc_len;
} else {
col_pos = child_id / cont->grid->row_dsc_len;
row_pos = child_id % cont->grid->row_dsc_len;
}
}
}
lv_coord_t col_w = calc->col_dsc[col_pos + col_span] - calc->col_dsc[col_pos];
lv_coord_t row_h = calc->row_dsc[row_pos + row_span] - calc->row_dsc[row_pos];
uint8_t x_flag = _GRID_GET_CELL_FLAG(item->x_set);
uint8_t y_flag = _GRID_GET_CELL_FLAG(item->y_set);
lv_coord_t x;
lv_coord_t y;
lv_coord_t w = lv_obj_get_width(item);
lv_coord_t h = lv_obj_get_height(item);
switch(x_flag) {
case LV_GRID_START:
x = calc->col_dsc[col_pos];
break;
case LV_GRID_STRETCH:
x = calc->col_dsc[col_pos];
w = col_w;
item->w_set = LV_SIZE_STRETCH;
break;
case LV_GRID_CENTER:
x = calc->col_dsc[col_pos] + (col_w - w) / 2;
break;
case LV_GRID_END:
x = calc->col_dsc[col_pos + 1] - lv_obj_get_width(item);
break;
}
switch(y_flag) {
case LV_GRID_START:
y = calc->row_dsc[row_pos];
break;
case LV_GRID_STRETCH:
y = calc->row_dsc[row_pos];
item->h_set = LV_SIZE_STRETCH;
h = row_h;
break;
case LV_GRID_CENTER:
y = calc->row_dsc[row_pos] + (row_h - h) / 2;
break;
case LV_GRID_END:
y = calc->row_dsc[row_pos + 1] - lv_obj_get_height(item);
break;
}
/*Set a new size if required*/
if(lv_obj_get_width(item) != w || lv_obj_get_height(item) != h) {
lv_area_t old_coords;
lv_area_copy(&old_coords, &item->coords);
lv_obj_invalidate(item);
lv_area_set_width(&item->coords, w);
lv_area_set_height(&item->coords, h);
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) {
if(hint->grid_abs.x + x == item->coords.x1 && hint->grid_abs.y + y == item->coords.y1) moved = false;
}
if(moved) _lv_obj_move_to(item, x, y, false);
}

View File

@ -113,15 +113,15 @@ void lv_grid_set_template(lv_grid_t * grid, const lv_coord_t * col_dsc, const lv
void lv_grid_set_place_content(lv_grid_t * grid, uint8_t col_place, uint8_t row_place); void lv_grid_set_place_content(lv_grid_t * grid, uint8_t col_place, uint8_t row_place);
void grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc); void _lv_grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
void grid_calc_free(_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); bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj); bool _lv_grid_has_fr_row(struct _lv_obj_t * obj);
void lv_grid_full_refr(lv_obj_t * cont); void _lv_grid_full_refresh(lv_obj_t * cont);
void lv_grid_item_refr_pos(lv_obj_t * item); void lv_grid_item_refr_pos(lv_obj_t * item);

View File

@ -1053,7 +1053,7 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
lv_obj_t * found_p = NULL; lv_obj_t * found_p = NULL;
/*If the point is on this object check its children too*/ /*If the point is on this object check its children too*/
if(lv_obj_hittest(obj, point)) { if(lv_obj_hit_test(obj, point)) {
lv_obj_t * i; lv_obj_t * i;
_LV_LL_READ(obj->child_ll, i) { _LV_LL_READ(obj->child_ll, i) {
@ -1088,7 +1088,7 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
static void indev_click_focus(lv_indev_proc_t * proc) static void indev_click_focus(lv_indev_proc_t * proc)
{ {
/*Handle click focus*/ /*Handle click focus*/
lv_obj_t * obj_to_focus = lv_obj_get_focused_obj(indev_obj_act); lv_obj_t * obj_to_focus = _lv_obj_get_focused_obj(indev_obj_act);
if(lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_PRESS_LOCK) == false && if(lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_PRESS_LOCK) == false &&
proc->types.pointer.last_pressed != obj_to_focus) { proc->types.pointer.last_pressed != obj_to_focus) {
#if LV_USE_GROUP #if LV_USE_GROUP

View File

@ -1,5 +1,5 @@
/** /**
* @file lv_scroll.c * @file lv_indev_scroll.c
* *
*/ */

View File

@ -48,8 +48,7 @@
#define LV_OBJX_NAME "lv_obj" #define LV_OBJX_NAME "lv_obj"
#define LV_OBJ_DEF_WIDTH (LV_DPX(100)) #define LV_OBJ_DEF_WIDTH (LV_DPX(100))
#define LV_OBJ_DEF_HEIGHT (LV_DPX(50)) #define LV_OBJ_DEF_HEIGHT (LV_DPX(50))
#define SCROLLBAR_MIN_SIZE (LV_DPX(10)) #define GRID_DEBUG 0 /*Draw rectangles on grid cells*/
#define GRID_DEBUG 1 /*Draw rectangles on grid cells*/
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -70,8 +69,6 @@ static void lv_event_mark_deleted(lv_obj_t * obj);
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
static void lv_obj_del_async_cb(void * obj); static void lv_obj_del_async_cb(void * obj);
static void obj_del_core(lv_obj_t * obj); static void obj_del_core(lv_obj_t * obj);
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc);
static void scrollbar_draw(lv_obj_t * obj, const lv_area_t * clip_area);
static void base_dir_refr_children(lv_obj_t * obj); static void base_dir_refr_children(lv_obj_t * obj);
/********************** /**********************
@ -270,8 +267,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
_lv_memset_00(&new_obj->ext_click_pad, sizeof(new_obj->ext_click_pad)); _lv_memset_00(&new_obj->ext_click_pad, sizeof(new_obj->ext_click_pad));
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
new_obj->ext_click_pad_hor = 0; new_obj->ext_click_pad = 0;
new_obj->ext_click_pad_ver = 0;
#endif #endif
/*Init. user date*/ /*Init. user date*/
@ -286,7 +282,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
#endif #endif
/*Set attributes*/ /*Set attributes*/
new_obj->adv_hittest = 0;
new_obj->scroll_mode = LV_SCROLL_MODE_AUTO; new_obj->scroll_mode = LV_SCROLL_MODE_AUTO;
new_obj->scroll_dir = LV_DIR_ALL; new_obj->scroll_dir = LV_DIR_ALL;
new_obj->flags = LV_OBJ_FLAG_CLICKABLE; new_obj->flags = LV_OBJ_FLAG_CLICKABLE;
@ -313,8 +308,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_copy(&new_obj->ext_click_pad, &copy->ext_click_pad); lv_area_copy(&new_obj->ext_click_pad, &copy->ext_click_pad);
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
new_obj->ext_click_pad_hor = copy->ext_click_pad_hor; new_obj->ext_click_pad = copy->ext_click_pad;
new_obj->ext_click_pad_ver = copy->ext_click_pad_ver;
#endif #endif
/*Set user data*/ /*Set user data*/
@ -327,7 +321,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
new_obj->event_cb = copy->event_cb; new_obj->event_cb = copy->event_cb;
/*Copy attributes*/ /*Copy attributes*/
new_obj->adv_hittest = copy->adv_hittest;
new_obj->flags = copy->flags; new_obj->flags = copy->flags;
new_obj->scroll_mode = copy->scroll_mode; new_obj->scroll_mode = copy->scroll_mode;
@ -677,14 +670,13 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
obj->ext_click_pad.y1 = top; obj->ext_click_pad.y1 = top;
obj->ext_click_pad.y2 = bottom; obj->ext_click_pad.y2 = bottom;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
obj->ext_click_pad_hor = LV_MATH_MAX(left, right); obj->ext_click_pad = LV_MATH_MAX4(left, right, top, bottom);
obj->ext_click_pad_ver = LV_MATH_MAX(top, bottom);
#else #else
(void)obj; /*Unused*/ LV_UNUSED(obj);
(void)left; /*Unused*/ LV_UNUSED(left);
(void)right; /*Unused*/ LV_UNUSED(right);
(void)top; /*Unused*/ LV_UNUSED(top);
(void)bottom; /*Unused*/ LV_UNUSED(bottom);
#endif #endif
} }
@ -696,19 +688,6 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
* Attribute set * Attribute set
*----------------*/ *----------------*/
/**
* Set whether advanced hit-testing is enabled on an object
* @param obj pointer to an object
* @param en true: advanced hit-testing is enabled
*/
void lv_obj_set_adv_hittest(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->adv_hittest = en == false ? 0 : 1;
}
/** /**
* Set the base direction of the object * Set the base direction of the object
* @param obj pointer to an object * @param obj pointer to an object
@ -1050,19 +1029,6 @@ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size)
return (void *)obj->ext_attr; return (void *)obj->ext_attr;
} }
/**
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object to refresh the extended draw area.
* he object needs to be invalidated by `lv_obj_invalidate(obj)` manually after this function.
* @param obj pointer to an object
*/
void lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->ext_draw_pad = 0;
obj->signal_cb(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, NULL);
}
/*======================= /*=======================
* Getter functions * Getter functions
@ -1201,93 +1167,90 @@ uint16_t lv_obj_count_children_recursive(const lv_obj_t * obj)
*--------------------*/ *--------------------*/
/** /**
* Get the left padding of extended clickable area * Get the extended extended clickable area in a direction
* @param obj pointer to an object * @param obj pointer to an object
* @param dir in which direction get the extended area (`LV_DIR_LEFT/RIGHT/TOP`)
* @return the extended left padding * @return the extended left padding
*/ */
lv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj) lv_coord_t lv_obj_get_ext_click_area(const lv_obj_t * obj, lv_dir_t dir)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_OFF
return obj->ext_click_pad_hor; LV_UNUSED(obj);
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL LV_UNUSED(dir);
return obj->ext_click_pad.x1;
#else
(void)obj; /*Unused*/
return 0; return 0;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
LV_UNUSED(dir);
return obj->ext_click_pad;
#else
switch(dir) {
case LV_DIR_LEFT:
return obj->ext_click_pad.x1;
case LV_DIR_RIGHT:
return obj->ext_click_pad.x2;
case LV_DIR_TOP:
return obj->ext_click_pad.y1;
case LV_DIR_BOTTOM:
return obj->ext_click_pad.y2;
default:
return 0;
}
#endif #endif
} }
/**
* Get the right padding of extended clickable area
* @param obj pointer to an object
* @return the extended right padding
*/
lv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/**
* Check if a given screen-space point is on an object's coordinates.
* This method is intended to be used mainly by advanced hit testing algorithms to check
* whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/
bool _lv_obj_is_click_point_on(lv_obj_t * obj, const lv_point_t * point)
{
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_hor; lv_area_t ext_area;
ext_area.x1 = obj->coords.x1 - obj->ext_click_pad;
ext_area.x2 = obj->coords.x2 + obj->ext_click_pad;
ext_area.y1 = obj->coords.y1 - obj->ext_click_pad;
ext_area.y2 = obj->coords.y2 + obj->ext_click_pad;
if(!_lv_area_is_point_on(&ext_area, point, 0)) {
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
return obj->ext_click_pad.x2; lv_area_t ext_area;
ext_area.x1 = obj->coords.x1 - obj->ext_click_pad.x1;
ext_area.x2 = obj->coords.x2 + obj->ext_click_pad.x2;
ext_area.y1 = obj->coords.y1 - obj->ext_click_pad.y1;
ext_area.y2 = obj->coords.y2 + obj->ext_click_pad.y2;
if(!_lv_area_is_point_on(&ext_area, point, 0)) {
#else #else
(void)obj; /*Unused*/ if(!_lv_area_is_point_on(&obj->coords, point, 0)) {
return 0;
#endif #endif
return false;
}
return true;
} }
/** /**
* Get the top padding of extended clickable area * Hit-test an object given a particular point in screen space.
* @param obj pointer to an object * @param obj object to hit-test
* @return the extended top padding * @param point screen-space point
* @return true if the object is considered under the point
*/ */
lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj) bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); if(lv_obj_has_flag(obj, LV_OBJ_FLAG_ADV_HITTEST)) {
lv_hit_test_info_t hit_info;
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY hit_info.point = point;
return obj->ext_click_pad_ver; hit_info.result = true;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL obj->signal_cb(obj, LV_SIGNAL_HIT_TEST, &hit_info);
return obj->ext_click_pad.y1; return hit_info.result;
#else }
(void)obj; /*Unused*/ else {
return 0; return _lv_obj_is_click_point_on(obj, point);
#endif }
} }
/**
* Get the bottom padding of extended clickable area
* @param obj pointer to an object
* @return the extended bottom padding
*/
lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_ver;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
return obj->ext_click_pad.y2;
#else
(void)obj; /*Unused*/
return 0;
#endif
}
/**
* Get the extended size attribute of an object
* @param obj pointer to an object
* @return the extended size attribute
*/
lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->ext_draw_pad;
}
/*----------------- /*-----------------
* Appearance get * Appearance get
*---------------*/ *---------------*/
@ -1304,19 +1267,6 @@ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f)
return obj->flags & f ? true : false; return obj->flags & f ? true : false;
} }
/**
* Get whether advanced hit-testing is enabled on an object
* @param obj pointer to an object
* @return true: advanced hit-testing is enabled
*/
bool lv_obj_get_adv_hittest(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return obj->adv_hittest == 0 ? false : true;
}
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj) lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
@ -1525,7 +1475,7 @@ bool lv_obj_is_focused(const lv_obj_t * obj)
* @param obj the start object * @param obj the start object
* @return the object to really focus * @return the object to really focus
*/ */
lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj) lv_obj_t * _lv_obj_get_focused_obj(const lv_obj_t * obj)
{ {
if(obj == NULL) return NULL; if(obj == NULL) return NULL;
const lv_obj_t * focus_obj = obj; const lv_obj_t * focus_obj = obj;
@ -1536,26 +1486,6 @@ lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj)
return (lv_obj_t *)focus_obj; return (lv_obj_t *)focus_obj;
} }
/**
* Hit-test an object given a particular point in screen space.
* @param obj object to hit-test
* @param point screen-space point
* @return true if the object is considered under the point
*/
bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point)
{
if(obj->adv_hittest) {
lv_hit_test_info_t hit_info;
hit_info.point = point;
hit_info.result = true;
obj->signal_cb(obj, LV_SIGNAL_HIT_TEST, &hit_info);
return hit_info.result;
}
else
return lv_obj_is_point_on_coords(obj, point);
}
/** /**
* Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal * Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal
* @param obj pointer to an object * @param obj pointer to an object
@ -1563,7 +1493,7 @@ bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point)
* @param name name of the object. E.g. "lv_btn". (Only the pointer is saved) * @param name name of the object. E.g. "lv_btn". (Only the pointer is saved)
* @return LV_RES_OK * @return LV_RES_OK
*/ */
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name) lv_res_t _lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name)
{ {
uint8_t i; uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
@ -1574,314 +1504,6 @@ lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name)
return LV_RES_OK; return LV_RES_OK;
} }
/**
* Initialize a rectangle descriptor from an object's styles
* @param obj pointer to an object
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_STYLE_REL` or `LV_PAGE_STYLE_SCRL`
* @param draw_dsc the descriptor the initialize
* @note Only the relevant fields will be set.
* E.g. if `border width == 0` the other border properties won't be evaluated.
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t * draw_dsc)
{
draw_dsc->radius = lv_obj_get_style_radius(obj, part);
#if LV_USE_OPA_SCALE
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
if(opa_scale <= LV_OPA_MIN) {
draw_dsc->bg_opa = LV_OPA_TRANSP;
draw_dsc->border_opa = LV_OPA_TRANSP;
draw_dsc->shadow_opa = LV_OPA_TRANSP;
draw_dsc->pattern_opa = LV_OPA_TRANSP;
draw_dsc->value_opa = LV_OPA_TRANSP;
return;
}
#endif
if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
if(draw_dsc->bg_opa > LV_OPA_MIN) {
draw_dsc->bg_color = lv_obj_get_style_bg_color(obj, part);
draw_dsc->bg_grad_dir = lv_obj_get_style_bg_grad_dir(obj, part);
if(draw_dsc->bg_grad_dir != LV_GRAD_DIR_NONE) {
draw_dsc->bg_grad_color = lv_obj_get_style_bg_grad_color(obj, part);
draw_dsc->bg_main_color_stop = lv_obj_get_style_bg_main_stop(obj, part);
draw_dsc->bg_grad_color_stop = lv_obj_get_style_bg_grad_stop(obj, part);
}
#if LV_USE_BLEND_MODES
draw_dsc->bg_blend_mode = lv_obj_get_style_bg_blend_mode(obj, part);
#endif
}
}
draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
if(draw_dsc->border_width) {
if(draw_dsc->border_opa != LV_OPA_TRANSP) {
draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
if(draw_dsc->border_opa > LV_OPA_MIN) {
draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
draw_dsc->border_color = lv_obj_get_style_border_color(obj, part);
}
#if LV_USE_BLEND_MODES
draw_dsc->border_blend_mode = lv_obj_get_style_border_blend_mode(obj, part);
#endif
}
}
#if LV_USE_OUTLINE
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
if(draw_dsc->outline_width) {
if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
if(draw_dsc->outline_opa > LV_OPA_MIN) {
draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
draw_dsc->outline_color = lv_obj_get_style_outline_color(obj, part);
}
#if LV_USE_BLEND_MODES
draw_dsc->outline_blend_mode = lv_obj_get_style_outline_blend_mode(obj, part);
#endif
}
}
#endif
#if LV_USE_PATTERN
draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part);
if(draw_dsc->pattern_image) {
if(draw_dsc->pattern_opa != LV_OPA_TRANSP) {
draw_dsc->pattern_opa = lv_obj_get_style_pattern_opa(obj, part);
if(draw_dsc->pattern_opa > LV_OPA_MIN) {
draw_dsc->pattern_recolor_opa = lv_obj_get_style_pattern_recolor_opa(obj, part);
draw_dsc->pattern_repeat = lv_obj_get_style_pattern_repeat(obj, part);
if(lv_img_src_get_type(draw_dsc->pattern_image) == LV_IMG_SRC_SYMBOL) {
draw_dsc->pattern_recolor = lv_obj_get_style_pattern_recolor(obj, part);
draw_dsc->pattern_font = lv_obj_get_style_text_font(obj, part);
}
else if(draw_dsc->pattern_recolor_opa > LV_OPA_MIN) {
draw_dsc->pattern_recolor = lv_obj_get_style_pattern_recolor(obj, part);
}
#if LV_USE_BLEND_MODES
draw_dsc->pattern_blend_mode = lv_obj_get_style_pattern_blend_mode(obj, part);
#endif
}
}
}
#endif
#if LV_USE_SHADOW
draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
if(draw_dsc->shadow_width) {
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part);
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
draw_dsc->shadow_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part);
draw_dsc->shadow_color = lv_obj_get_style_shadow_color(obj, part);
#if LV_USE_BLEND_MODES
draw_dsc->shadow_blend_mode = lv_obj_get_style_shadow_blend_mode(obj, part);
#endif
}
}
}
#endif
#if LV_USE_VALUE_STR
draw_dsc->value_str = lv_obj_get_style_value_str(obj, part);
if(draw_dsc->value_str) {
if(draw_dsc->value_opa > LV_OPA_MIN) {
draw_dsc->value_opa = lv_obj_get_style_value_opa(obj, part);
if(draw_dsc->value_opa > LV_OPA_MIN) {
draw_dsc->value_ofs_x = lv_obj_get_style_value_ofs_x(obj, part);
draw_dsc->value_ofs_y = lv_obj_get_style_value_ofs_y(obj, part);
draw_dsc->value_color = lv_obj_get_style_value_color(obj, part);
draw_dsc->value_font = lv_obj_get_style_value_font(obj, part);
draw_dsc->value_letter_space = lv_obj_get_style_value_letter_space(obj, part);
draw_dsc->value_line_space = lv_obj_get_style_value_line_space(obj, part);
draw_dsc->value_align = lv_obj_get_style_value_align(obj, part);
#if LV_USE_BLEND_MODES
draw_dsc->value_blend_mode = lv_obj_get_style_value_blend_mode(obj, part);
#endif
}
}
}
#endif
#if LV_USE_OPA_SCALE
if(opa_scale < LV_OPA_MAX) {
draw_dsc->bg_opa = (uint16_t)((uint16_t)draw_dsc->bg_opa * opa_scale) >> 8;
draw_dsc->border_opa = (uint16_t)((uint16_t)draw_dsc->border_opa * opa_scale) >> 8;
draw_dsc->shadow_opa = (uint16_t)((uint16_t)draw_dsc->shadow_opa * opa_scale) >> 8;
draw_dsc->pattern_opa = (uint16_t)((uint16_t)draw_dsc->pattern_opa * opa_scale) >> 8;
draw_dsc->value_opa = (uint16_t)((uint16_t)draw_dsc->value_opa * opa_scale) >> 8;
}
#endif
}
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t part, lv_draw_label_dsc_t * draw_dsc)
{
draw_dsc->opa = lv_obj_get_style_text_opa(obj, part);
if(draw_dsc->opa <= LV_OPA_MIN) return;
#if LV_USE_OPA_SCALE
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
if(opa_scale < LV_OPA_MAX) {
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
}
if(draw_dsc->opa <= LV_OPA_MIN) return;
#endif
draw_dsc->color = lv_obj_get_style_text_color(obj, part);
draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part);
draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part);
draw_dsc->decor = lv_obj_get_style_text_decor(obj, part);
#if LV_USE_BLEND_MODES
draw_dsc->blend_mode = lv_obj_get_style_text_blend_mode(obj, part);
#endif
draw_dsc->font = lv_obj_get_style_text_font(obj, part);
if(draw_dsc->sel_start != LV_DRAW_LABEL_NO_TXT_SEL && draw_dsc->sel_end != LV_DRAW_LABEL_NO_TXT_SEL) {
draw_dsc->color = lv_obj_get_style_text_sel_color(obj, part);
}
#if LV_USE_BIDI
draw_dsc->bidi_dir = lv_obj_get_base_dir(obj);
#endif
}
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc)
{
draw_dsc->opa = lv_obj_get_style_image_opa(obj, part);
if(draw_dsc->opa <= LV_OPA_MIN) return;
#if LV_USE_OPA_SCALE
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
if(opa_scale < LV_OPA_MAX) {
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
}
if(draw_dsc->opa <= LV_OPA_MIN) return;
#endif
draw_dsc->angle = 0;
draw_dsc->zoom = LV_IMG_ZOOM_NONE;
draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
draw_dsc->recolor_opa = lv_obj_get_style_image_recolor_opa(obj, part);
if(draw_dsc->recolor_opa > 0) {
draw_dsc->recolor = lv_obj_get_style_image_recolor(obj, part);
}
#if LV_USE_BLEND_MODES
draw_dsc->blend_mode = lv_obj_get_style_image_blend_mode(obj, part);
#endif
}
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc)
{
draw_dsc->width = lv_obj_get_style_line_width(obj, part);
if(draw_dsc->width == 0) return;
draw_dsc->opa = lv_obj_get_style_line_opa(obj, part);
if(draw_dsc->opa <= LV_OPA_MIN) return;
#if LV_USE_OPA_SCALE
lv_opa_t opa_scale = lv_obj_get_style_opa_scale(obj, part);
if(opa_scale < LV_OPA_MAX) {
draw_dsc->opa = (uint16_t)((uint16_t)draw_dsc->opa * opa_scale) >> 8;
}
if(draw_dsc->opa <= LV_OPA_MIN) return;
#endif
draw_dsc->color = lv_obj_get_style_line_color(obj, part);
draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part);
if(draw_dsc->dash_width) {
draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part);
}
draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part);
draw_dsc->round_end = draw_dsc->round_start;
#if LV_USE_BLEND_MODES
draw_dsc->blend_mode = lv_obj_get_style_line_blend_mode(obj, part);
#endif
}
/**
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
* @param obj pointer to an object
* @param part part of the object
*/
lv_coord_t lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part)
{
lv_coord_t s = 0;
lv_coord_t sh_width = lv_obj_get_style_shadow_width(obj, part);
if(sh_width) {
lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part);
if(sh_opa > LV_OPA_MIN) {
sh_width = sh_width / 2; /*THe blur adds only half width*/
sh_width++;
sh_width += lv_obj_get_style_shadow_spread(obj, part);
lv_style_int_t sh_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
lv_style_int_t sh_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
sh_width += LV_MATH_MAX(LV_MATH_ABS(sh_ofs_x), LV_MATH_ABS(sh_ofs_y));
s = LV_MATH_MAX(s, sh_width);
}
}
const char * value_str = lv_obj_get_style_value_str(obj, part);
if(value_str) {
lv_opa_t value_opa = lv_obj_get_style_value_opa(obj, part);
if(value_opa > LV_OPA_MIN) {
lv_style_int_t letter_space = lv_obj_get_style_value_letter_space(obj, part);
lv_style_int_t line_space = lv_obj_get_style_value_letter_space(obj, part);
const lv_font_t * font = lv_obj_get_style_value_font(obj, part);
lv_point_t txt_size;
_lv_txt_get_size(&txt_size, value_str, font, letter_space, line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
lv_area_t value_area;
value_area.x1 = 0;
value_area.y1 = 0;
value_area.x2 = txt_size.x - 1;
value_area.y2 = txt_size.y - 1;
lv_style_int_t align = lv_obj_get_style_value_align(obj, part);
lv_style_int_t xofs = lv_obj_get_style_value_ofs_x(obj, part);
lv_style_int_t yofs = lv_obj_get_style_value_ofs_y(obj, part);
lv_point_t p_align;
_lv_area_align(&obj->coords, &value_area, align, &p_align);
value_area.x1 += p_align.x + xofs;
value_area.y1 += p_align.y + yofs;
value_area.x2 += p_align.x + xofs;
value_area.y2 += p_align.y + yofs;
s = LV_MATH_MAX(s, obj->coords.x1 - value_area.x1);
s = LV_MATH_MAX(s, obj->coords.y1 - value_area.y1);
s = LV_MATH_MAX(s, value_area.x2 - obj->coords.x2);
s = LV_MATH_MAX(s, value_area.y2 - obj->coords.y2);
}
}
lv_style_int_t outline_width = lv_obj_get_style_outline_width(obj, part);
if(outline_width) {
lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part);
if(outline_opa > LV_OPA_MIN) {
lv_style_int_t outline_pad = lv_obj_get_style_outline_pad(obj, part);
s = LV_MATH_MAX(s, outline_pad + outline_width);
}
}
lv_coord_t w = lv_obj_get_style_transform_width(obj, part);
lv_coord_t h = lv_obj_get_style_transform_height(obj, part);
lv_coord_t wh = LV_MATH_MAX(w, h);
if(wh > 0) s += wh;
return s;
}
/** /**
* Check if any object has a given type * Check if any object has a given type
@ -1889,7 +1511,7 @@ lv_coord_t lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part)
* @param obj_type type of the object. (e.g. "lv_btn") * @param obj_type type of the object. (e.g. "lv_btn")
* @return true: valid * @return true: valid
*/ */
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type) bool _lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
{ {
if(obj_type[0] == '\0') return true; if(obj_type[0] == '\0') return true;
@ -1911,7 +1533,7 @@ bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
* @param obj_type type of the object. (e.g. "lv_btn") * @param obj_type type of the object. (e.g. "lv_btn")
* @return true: valid * @return true: valid
*/ */
bool lv_debug_check_obj_valid(const lv_obj_t * obj) bool _lv_debug_check_obj_valid(const lv_obj_t * obj)
{ {
lv_disp_t * disp = lv_disp_get_next(NULL); lv_disp_t * disp = lv_disp_get_next(NULL);
while(disp) { while(disp) {
@ -2086,7 +1708,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
} }
} }
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
scrollbar_draw(obj, clip_area); _lv_obj_draw_scrollbar(obj, clip_area);
if(lv_obj_get_style_clip_corner(obj, LV_OBJ_PART_MAIN)) { if(lv_obj_get_style_clip_corner(obj, LV_OBJ_PART_MAIN)) {
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8); lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8);
@ -2118,7 +1740,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
/*Draw the grid cells*/ /*Draw the grid cells*/
if(obj->grid) { if(obj->grid) {
_lv_grid_calc_t calc; _lv_grid_calc_t calc;
grid_calc(obj, &calc); _lv_grid_calc(obj, &calc);
/*Create a color unique to this object. */ /*Create a color unique to this object. */
lv_color_t c = lv_color_hex(((lv_uintptr_t) obj) & 0xFFFFFF); lv_color_t c = lv_color_hex(((lv_uintptr_t) obj) & 0xFFFFFF);
@ -2151,7 +1773,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
} }
grid_calc_free(&calc); _lv_grid_calc_free(&calc);
} }
#endif #endif
} }
@ -2189,7 +1811,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
else info->result = NULL; else info->result = NULL;
return LV_RES_OK; return LV_RES_OK;
} }
else if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); else if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_res_t res = LV_RES_OK; lv_res_t res = LV_RES_OK;
@ -2197,7 +1819,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if((lv_area_get_width(param) != lv_obj_get_width(obj) && _lv_grid_has_fr_col(obj)) || if((lv_area_get_width(param) != lv_obj_get_width(obj) && _lv_grid_has_fr_col(obj)) ||
(lv_area_get_height(param) != lv_obj_get_height(obj) && _lv_grid_has_fr_row(obj))) (lv_area_get_height(param) != lv_obj_get_height(obj) && _lv_grid_has_fr_row(obj)))
{ {
lv_grid_full_refr(obj); _lv_grid_full_refresh(obj);
} }
} }
else if(sign == LV_SIGNAL_CHILD_CHG) { else if(sign == LV_SIGNAL_CHILD_CHG) {
@ -2208,9 +1830,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(obj->grid) { if(obj->grid) {
lv_obj_t * child = param; lv_obj_t * child = param;
if(child) { if(child) {
if(_lv_obj_is_grid_item(child)) lv_grid_full_refr(obj); if(_lv_obj_is_grid_item(child)) _lv_grid_full_refresh(obj);
} else { } else {
lv_grid_full_refr(obj); _lv_grid_full_refresh(obj);
} }
} }
} }
@ -2225,11 +1847,11 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
} }
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_coord_t d = lv_obj_get_draw_rect_ext_pad_size(obj, LV_OBJ_PART_MAIN); lv_coord_t d = 0;//_lv_obj_get_draw_rect_ext_pad_size(obj, LV_OBJ_PART_MAIN);
obj->ext_draw_pad = LV_MATH_MAX(obj->ext_draw_pad, d); obj->ext_draw_pad = LV_MATH_MAX(obj->ext_draw_pad, d);
} }
else if(sign == LV_SIGNAL_STYLE_CHG) { else if(sign == LV_SIGNAL_STYLE_CHG) {
if(_lv_obj_is_grid_item(obj)) lv_grid_full_refr(obj); if(_lv_obj_is_grid_item(obj)) _lv_grid_full_refresh(obj);
lv_obj_t * child = lv_obj_get_child(obj, NULL); lv_obj_t * child = lv_obj_get_child(obj, NULL);
while(child) { while(child) {
@ -2243,8 +1865,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) { if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(obj, obj->w_set, obj->h_set); lv_obj_set_size(obj, obj->w_set, obj->h_set);
} }
// if(lv_obj_is_grid_item(obj)) lv_grid_full_refr(lv_obj_get_parent(obj)); _lv_obj_refresh_ext_draw_pad(obj);
lv_obj_refresh_ext_draw_pad(obj);
} }
else if(sign == LV_SIGNAL_PRESSED) { else if(sign == LV_SIGNAL_PRESSED) {
lv_obj_add_state(obj, LV_STATE_PRESSED); lv_obj_add_state(obj, LV_STATE_PRESSED);
@ -2262,14 +1883,14 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
state |= LV_STATE_EDITED; state |= LV_STATE_EDITED;
/*if using focus mode, change target to parent*/ /*if using focus mode, change target to parent*/
obj = lv_obj_get_focused_obj(obj); obj = _lv_obj_get_focused_obj(obj);
lv_obj_add_state(obj, state); lv_obj_add_state(obj, state);
} }
else { else {
/*if using focus mode, change target to parent*/ /*if using focus mode, change target to parent*/
obj = lv_obj_get_focused_obj(obj); obj = _lv_obj_get_focused_obj(obj);
lv_obj_add_state(obj, LV_STATE_FOCUSED); lv_obj_add_state(obj, LV_STATE_FOCUSED);
lv_obj_clear_state(obj, LV_STATE_EDITED); lv_obj_clear_state(obj, LV_STATE_EDITED);
@ -2278,7 +1899,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
else if(sign == LV_SIGNAL_DEFOCUS) { else if(sign == LV_SIGNAL_DEFOCUS) {
/*if using focus mode, change target to parent*/ /*if using focus mode, change target to parent*/
obj = lv_obj_get_focused_obj(obj); obj = _lv_obj_get_focused_obj(obj);
lv_obj_clear_state(obj, LV_STATE_FOCUSED | LV_STATE_EDITED); lv_obj_clear_state(obj, LV_STATE_FOCUSED | LV_STATE_EDITED);
} }
@ -2314,168 +1935,3 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin
return false; return false;
} }
static lv_res_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc)
{
lv_draw_rect_dsc_init(dsc);
dsc->bg_opa = lv_obj_get_style_scrollbar_bg_opa(obj, LV_OBJ_PART_MAIN);
if(dsc->bg_opa > LV_OPA_MIN) {
dsc->bg_color = lv_obj_get_style_scrollbar_bg_color(obj, LV_OBJ_PART_MAIN);
}
dsc->border_opa = lv_obj_get_style_scrollbar_border_opa(obj, LV_OBJ_PART_MAIN);
if(dsc->border_opa > LV_OPA_MIN) {
dsc->border_width = lv_obj_get_style_scrollbar_border_width(obj, LV_OBJ_PART_MAIN);
if(dsc->border_width > 0) {
dsc->border_color = lv_obj_get_style_scrollbar_border_color(obj, LV_OBJ_PART_MAIN);
} else {
dsc->border_opa = LV_OPA_TRANSP;
}
}
if(dsc->bg_opa != LV_OPA_TRANSP || dsc->border_opa != LV_OPA_TRANSP) {
dsc->radius = lv_obj_get_style_scrollbar_radius(obj, LV_OBJ_PART_MAIN);
return LV_RES_OK;
} else {
return LV_RES_INV;
}
}
static void scrollbar_draw(lv_obj_t * obj, const lv_area_t * clip_area)
{
lv_scroll_dir_t sm = lv_obj_get_scroll_mode(obj);
if(sm == LV_SCROLL_MODE_OFF) {
return;
}
lv_coord_t st = lv_obj_get_scroll_top(obj);
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
lv_coord_t sl = lv_obj_get_scroll_left(obj);
lv_coord_t sr = lv_obj_get_scroll_right(obj);
/*Return if too small content to scroll*/
if(sm == LV_SCROLL_MODE_AUTO && st <= 0 && sb <= 0 && sl <= 0 && sr <= 0) {
return;
}
/*If there is no indev scrolling this object but the moe is active return*/
lv_indev_t * indev = lv_indev_get_next(NULL);
if(sm == LV_SCROLL_MODE_ACTIVE) {
bool found = false;
while(indev) {
if(lv_indev_get_scroll_obj(indev) == obj) {
found = true;
break;
}
indev = lv_indev_get_next(indev);
}
if(!found) {
return;
}
}
lv_coord_t end_space = lv_obj_get_style_scrollbar_space_end(obj, LV_OBJ_PART_MAIN);
lv_coord_t side_space = lv_obj_get_style_scrollbar_space_side(obj, LV_OBJ_PART_MAIN);
lv_coord_t tickness = lv_obj_get_style_scrollbar_tickness(obj, LV_OBJ_PART_MAIN);
lv_coord_t obj_h = lv_obj_get_height(obj);
lv_coord_t obj_w = lv_obj_get_width(obj);
bool ver_draw = false;
if((sm == LV_SCROLL_MODE_ON) ||
(sm == LV_SCROLL_MODE_AUTO && (st > 0 || sb > 0)) ||
(sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_VER)) {
ver_draw = true;
}
bool hor_draw = false;
if((sm == LV_SCROLL_MODE_ON) ||
(sm == LV_SCROLL_MODE_AUTO && (sl > 0 || sr > 0)) ||
(sm == LV_SCROLL_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_SCROLL_DIR_HOR)) {
hor_draw = true;
}
lv_coord_t ver_reg_space = ver_draw ? tickness + side_space : 0;
lv_coord_t hor_req_space = hor_draw ? tickness + side_space : 0;
lv_coord_t rem;
lv_draw_rect_dsc_t draw_dsc;
lv_res_t sb_res = scrollbar_init_draw_dsc(obj, &draw_dsc);
if(sb_res != LV_RES_OK) return;
lv_area_t area;
area.y1 = obj->coords.y1;
area.y2 = obj->coords.y2;
area.x2 = obj->coords.x2 - side_space;
area.x1 = area.x2 - tickness;
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
if(ver_draw && _lv_area_is_on(&area, clip_area)) {
lv_coord_t content_h = obj_h + st + sb;
lv_coord_t sb_h = ((obj_h - end_space * 2 - hor_req_space) * obj_h) / content_h;
sb_h = LV_MATH_MAX(sb_h, SCROLLBAR_MIN_SIZE);
rem = (obj_h - end_space * 2 - hor_req_space) - sb_h; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
lv_coord_t scroll_h = content_h - obj_h; /*The size of the content which can be really scrolled*/
if(scroll_h <= 0) {
area.y1 = obj->coords.y1 + end_space;
area.y2 = obj->coords.y2 - end_space - hor_req_space - 1;
area.x2 = obj->coords.x2 - side_space;
area.x1 = area.x2 - tickness + 1;
} else {
lv_coord_t sb_y = (rem * sb) / scroll_h;
sb_y = rem - sb_y;
area.y1 = obj->coords.y1 + sb_y + end_space;
area.y2 = area.y1 + sb_h - 1;
area.x2 = obj->coords.x2 - side_space;
area.x1 = area.x2 - tickness;
if(area.y1 < obj->coords.y1 + end_space) {
area.y1 = obj->coords.y1 + end_space;
if(area.y1 + SCROLLBAR_MIN_SIZE > area.y2) area.y2 = area.y1 + SCROLLBAR_MIN_SIZE;
}
if(area.y2 > obj->coords.y2 - hor_req_space - end_space) {
area.y2 = obj->coords.y2 - hor_req_space - end_space;
if(area.y2 - SCROLLBAR_MIN_SIZE < area.y1) area.y1 = area.y2 - SCROLLBAR_MIN_SIZE;
}
}
lv_draw_rect(&area, clip_area, &draw_dsc);
}
area.y2 = obj->coords.y2 - side_space;
area.y1 =area.y2 - tickness;
area.x1 = obj->coords.x1;
area.x2 = obj->coords.x2;
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
if(hor_draw && _lv_area_is_on(&area, clip_area)) {
lv_coord_t content_w = obj_w + sl + sr;
lv_coord_t sb_w = ((obj_w - end_space * 2 - ver_reg_space) * obj_w) / content_w;
sb_w = LV_MATH_MAX(sb_w, SCROLLBAR_MIN_SIZE);
rem = (obj_w - end_space * 2 - ver_reg_space) - sb_w; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
lv_coord_t scroll_w = content_w - obj_w; /*The size of the content which can be really scrolled*/
if(scroll_w <= 0) {
area.y2 = obj->coords.y2 - side_space;
area.y1 = area.y2 - tickness + 1;
area.x1 = obj->coords.x1 + end_space;
area.x2 = obj->coords.x2 - end_space - ver_reg_space - 1;
} else {
lv_coord_t sb_x = (rem * sr) / scroll_w;
sb_x = rem - sb_x;
area.x1 = obj->coords.x1 + sb_x + end_space;
area.x2 = area.x1 + sb_w - 1;
area.y2 = obj->coords.y2 - side_space;
area.y1 = area.y2 - tickness;
if(area.x1 < obj->coords.x1 + end_space) {
area.x1 = obj->coords.x1 + end_space;
if(area.x1 + SCROLLBAR_MIN_SIZE > area.x2) area.x2 = area.x1 + SCROLLBAR_MIN_SIZE;
}
if(area.x2 > obj->coords.x2 - ver_reg_space - end_space) {
area.x2 = obj->coords.x2 - ver_reg_space - end_space;
if(area.x2 - SCROLLBAR_MIN_SIZE < area.x1) area.x1 = area.x2 - SCROLLBAR_MIN_SIZE;
}
}
lv_draw_rect(&area, clip_area, &draw_dsc);
}
}

View File

@ -57,7 +57,6 @@ extern "C" {
struct _lv_obj_t; struct _lv_obj_t;
/** Design modes */ /** Design modes */
enum { enum {
LV_DESIGN_DRAW_MAIN, /**< Draw the main portion of the object */ LV_DESIGN_DRAW_MAIN, /**< Draw the main portion of the object */
@ -196,12 +195,15 @@ enum {
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 7), LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 7),
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 8), LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 8),
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 9), LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 9),
LV_OBJ_FLAG_ADV_HITTEST = (1 << 10),
}; };
typedef uint16_t lv_obj_flag_t; typedef uint16_t lv_obj_flag_t;
#include "lv_obj_pos.h" #include "lv_obj_pos.h"
#include "lv_obj_scroll.h" #include "lv_obj_scroll.h"
#include "lv_obj_style.h"
#include "lv_obj_draw.h"
typedef struct _lv_obj_t { typedef struct _lv_obj_t {
@ -219,8 +221,7 @@ typedef struct _lv_obj_t {
lv_style_list_t style_list; lv_style_list_t style_list;
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
uint8_t ext_click_pad_hor; /**< Extra click padding in horizontal direction */ uint8_t ext_click_pad; /**< Extra click padding in all direction */
uint8_t ext_click_pad_ver; /**< Extra click padding in vertical direction */
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL #elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_t ext_click_pad; /**< Extra click padding area. */ lv_area_t ext_click_pad; /**< Extra click padding area. */
#endif #endif
@ -228,13 +229,12 @@ typedef struct _lv_obj_t {
lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */ lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */
/*Attributes and states*/ /*Attributes and states*/
lv_obj_flag_t flags : 9; lv_obj_flag_t flags;
lv_scroll_mode_t scroll_mode :2; /**< How to display scrollbars*/ lv_scroll_mode_t scroll_mode :2; /**< How to display scrollbars*/
lv_scroll_snap_align_t snap_align_x : 2; lv_scroll_snap_align_t snap_align_x : 2;
lv_scroll_snap_align_t snap_align_y : 2; lv_scroll_snap_align_t snap_align_y : 2;
lv_scroll_dir_t scroll_dir :4; lv_scroll_dir_t scroll_dir :4;
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */ lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */
lv_state_t state; lv_state_t state;
@ -426,13 +426,6 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
* Attribute set * Attribute set
*----------------*/ *----------------*/
/**
* Set whether advanced hit-testing is enabled on an object
* @param obj pointer to an object
* @param en true: advanced hit-testing is enabled
*/
void lv_obj_set_adv_hittest(lv_obj_t * obj, bool en);
/** /**
* Set the base direction of the object * Set the base direction of the object
* @param obj pointer to an object * @param obj pointer to an object
@ -441,6 +434,7 @@ void lv_obj_set_adv_hittest(lv_obj_t * obj, bool en);
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir); void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir);
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f); void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f); void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
/** /**
@ -528,7 +522,6 @@ const void * lv_event_get_data(void);
*/ */
void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb); void lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb);
/** /**
* Send an event to the object * Send an event to the object
* @param obj pointer to an object * @param obj pointer to an object
@ -556,13 +549,6 @@ void lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb);
*/ */
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size); void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);
/**
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object to refresh the extended draw area.
* he object needs to be invalidated by `lv_obj_invalidate(obj)` manually after this function.
* @param obj pointer to an object
*/
void lv_obj_refresh_ext_draw_pad(lv_obj_t * obj);
/*======================= /*=======================
* Getter functions * Getter functions
*======================*/ *======================*/
@ -627,59 +613,37 @@ uint16_t lv_obj_count_children_recursive(const lv_obj_t * obj);
*--------------------*/ *--------------------*/
/** /**
* Get the left padding of extended clickable area * Get the extended extended clickable area in a direction
* @param obj pointer to an object * @param obj pointer to an object
* @param dir in which direction get the extended area (`LV_DIR_LEFT/RIGHT/TOP`)
* @return the extended left padding * @return the extended left padding
*/ */
lv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj); lv_coord_t lv_obj_get_ext_click_area(const lv_obj_t * obj, lv_dir_t dir);
/** /**
* Get the right padding of extended clickable area * Check if a given screen-space point is on an object's coordinates.
* @param obj pointer to an object * This method is intended to be used mainly by advanced hit testing algorithms to check
* @return the extended right padding * whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/ */
lv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj); bool _lv_obj_is_click_point_on(lv_obj_t * obj, const lv_point_t * point);
/** /**
* Get the top padding of extended clickable area * Hit-test an object given a particular point in screen space.
* @param obj pointer to an object * @param obj object to hit-test
* @return the extended top padding * @param point screen-space point
* @return true if the object is considered under the point
*/ */
lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj); bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/**
* Get the bottom padding of extended clickable area
* @param obj pointer to an object
* @return the extended bottom padding
*/
lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj);
/**
* Get the extended size attribute of an object
* @param obj pointer to an object
* @return the extended size attribute
*/
lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
/*-----------------
* Appearance get
*---------------*/
/*----------------- /*-----------------
* Attribute get * Attribute get
*----------------*/ *----------------*/
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f); bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
/**
* Get whether advanced hit-testing is enabled on an object
* @param obj pointer to an object
* @return true: advanced hit-testing is enabled
*/
bool lv_obj_get_adv_hittest(const lv_obj_t * obj);
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj); lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj);
lv_state_t lv_obj_get_state(const lv_obj_t * obj, uint8_t part); lv_state_t lv_obj_get_state(const lv_obj_t * obj, uint8_t part);
@ -709,23 +673,13 @@ lv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj);
* Other get * Other get
*-----------------*/ *-----------------*/
/**
* Check if a given screen-space point is on an object's coordinates.
*
* This method is intended to be used mainly by advanced hit testing algorithms to check
* whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/
bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point);
/** /**
* Hit-test an object given a particular point in screen space. * Hit-test an object given a particular point in screen space.
* @param obj object to hit-test * @param obj object to hit-test
* @param point screen-space point * @param point screen-space point
* @return true if the object is considered under the point * @return true if the object is considered under the point
*/ */
bool lv_obj_hittest(lv_obj_t * obj, lv_point_t * point); bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/** /**
* Get the ext pointer * Get the ext pointer
@ -786,7 +740,7 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
* @param obj the start object * @param obj the start object
* @return the object to really focus * @return the object to really focus
*/ */
lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj); lv_obj_t * _lv_obj_get_focused_obj(const lv_obj_t * obj);
/*------------------- /*-------------------
* OTHER FUNCTIONS * OTHER FUNCTIONS
@ -798,30 +752,7 @@ lv_obj_t * lv_obj_get_focused_obj(const lv_obj_t * obj);
* @param name name of the object. E.g. "lv_btn". (Only the pointer is saved) * @param name name of the object. E.g. "lv_btn". (Only the pointer is saved)
* @return LV_RES_OK * @return LV_RES_OK
*/ */
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name); lv_res_t _lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
/**
* Initialize a rectangle descriptor from an object's styles
* @param obj pointer to an object
* @param type type of style. E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_SLIDER_KOB`
* @param draw_dsc the descriptor the initialize
* @note Only the relevant fields will be set.
* E.g. if `border width == 0` the other border properties won't be evaluated.
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t * draw_dsc);
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint8_t type, lv_draw_label_dsc_t * draw_dsc);
void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * draw_dsc);
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc);
/**
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
* @param obj pointer to an object
* @param part part of the object
*/
lv_coord_t lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part);
/** /**
@ -830,7 +761,7 @@ lv_coord_t lv_obj_get_draw_rect_ext_pad_size(lv_obj_t * obj, uint8_t part);
* @param obj_type type of the object. (e.g. "lv_btn") * @param obj_type type of the object. (e.g. "lv_btn")
* @return true: valid * @return true: valid
*/ */
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type); bool _lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
/** /**
* Check if any object is still "alive", and part of the hierarchy * Check if any object is still "alive", and part of the hierarchy
@ -838,11 +769,7 @@ bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
* @param obj_type type of the object. (e.g. "lv_btn") * @param obj_type type of the object. (e.g. "lv_btn")
* @return true: valid * @return true: valid
*/ */
bool lv_debug_check_obj_valid(const lv_obj_t * obj); bool _lv_debug_check_obj_valid(const lv_obj_t * obj);
void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);
#include "lv_obj_style.h"
/********************** /**********************
* MACROS * MACROS
@ -869,8 +796,8 @@ void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_di
# ifndef LV_DEBUG_IS_OBJ # ifndef LV_DEBUG_IS_OBJ
# define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \ # define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
lv_debug_check_obj_valid(obj_p) && \ _lv_debug_check_obj_valid(obj_p) && \
lv_debug_check_obj_type(obj_p, obj_type)) _lv_debug_check_obj_type(obj_p, obj_type))
# endif # endif

View File

@ -11,6 +11,7 @@
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define LV_OBJX_NAME "lv_obj"
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -61,30 +62,29 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
} }
/*If not grid item but has grid position set the position to 0*/ /*If not grid item but has grid position set the position to 0*/
if(!gi) { // if(!gi) {
if(_GRID_IS_CELL(x)) { // if(_GRID_IS_CELL(x)) {
obj->x_set = 0; // obj->x_set = 0;
x = 0; // x = 0;
} // }
if(_GRID_IS_CELL(y)) { // if(_GRID_IS_CELL(y)) {
obj->y_set = 0; // obj->y_set = 0;
y = 0; // y = 0;
} // }
} // }
/*If the object is on a grid item let the grid to position it. */ /*If the object is on a grid item let the grid to position it. */
if(gi) { if(gi) {
lv_area_t old_area;
lv_area_copy(&old_area, &obj->coords);
lv_grid_item_refr_pos(obj);
lv_obj_t * cont = lv_obj_get_parent(obj); lv_obj_t * cont = lv_obj_get_parent(obj);
/*If the item was moved and grid is implicit in the changed direction refresh the whole grid.*/ /*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 && (old_area.x1 != obj->coords.x1 || old_area.x2 != obj->coords.x2)) || if(cont->grid->col_dsc == NULL || cont->grid->row_dsc == NULL)
(cont->grid->row_dsc == NULL && (old_area.y1 != obj->coords.y1 || old_area.y2 != obj->coords.y2)))
{ {
lv_grid_full_refr(cont); _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);
} }
} else { } else {
_lv_obj_move_to(obj, x, y, true); _lv_obj_move_to(obj, x, y, true);
@ -442,40 +442,6 @@ lv_coord_t lv_obj_get_width_margin(lv_obj_t * obj)
return lv_obj_get_width(obj) + mleft + mright; return lv_obj_get_width(obj) + mleft + mright;
} }
/**
* Check if a given screen-space point is on an object's coordinates.
*
* This method is intended to be used mainly by advanced hit testing algorithms to check
* whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/
bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point)
{
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
lv_area_t ext_area;
ext_area.x1 = obj->coords.x1 - obj->ext_click_pad_hor;
ext_area.x2 = obj->coords.x2 + obj->ext_click_pad_hor;
ext_area.y1 = obj->coords.y1 - obj->ext_click_pad_ver;
ext_area.y2 = obj->coords.y2 + obj->ext_click_pad_ver;
if(!_lv_area_is_point_on(&ext_area, point, 0)) {
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_t ext_area;
ext_area.x1 = obj->coords.x1 - obj->ext_click_pad.x1;
ext_area.x2 = obj->coords.x2 + obj->ext_click_pad.x2;
ext_area.y1 = obj->coords.y1 - obj->ext_click_pad.y1;
ext_area.y2 = obj->coords.y2 + obj->ext_click_pad.y2;
if(!_lv_area_is_point_on(&ext_area, point, 0)) {
#else
if(!_lv_area_is_point_on(&obj->coords, point, 0)) {
#endif
return false;
}
return true;
}
/** /**
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)` * Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
* @param obj pointer to an object * @param obj pointer to an object
@ -486,6 +452,8 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_o
{ {
if(!w_out && !h_out) return; if(!w_out && !h_out) return;
// printf("auto size\n");
/*If no other effect the auto-size of zero by default*/ /*If no other effect the auto-size of zero by default*/
if(w_out) *w_out = 0; if(w_out) *w_out = 0;
if(h_out) *h_out = 0; if(h_out) *h_out = 0;
@ -495,10 +463,10 @@ void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_o
lv_coord_t grid_h = 0; lv_coord_t grid_h = 0;
if(obj->grid) { if(obj->grid) {
_lv_grid_calc_t calc; _lv_grid_calc_t calc;
grid_calc(obj, &calc); _lv_grid_calc(obj, &calc);
grid_w = calc.col_dsc[calc.col_dsc_len - 1] + lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN) + + lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN); grid_w = calc.col_dsc[calc.col_dsc_len - 1] + lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN) + + lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
grid_h = calc.row_dsc[calc.row_dsc_len - 1] + lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN) + lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);; grid_h = calc.row_dsc[calc.row_dsc_len - 1] + lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN) + lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);;
grid_calc_free(&calc); _lv_grid_calc_free(&calc);
} }
/*Get the children's most right and bottom position*/ /*Get the children's most right and bottom position*/

View File

@ -22,10 +22,7 @@ extern "C" {
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
/* Can't include lv_obj.h because it includes this header file */
struct _lv_obj_t; struct _lv_obj_t;
typedef struct _lv_obj_t lv_obj_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -34,79 +31,82 @@ typedef struct _lv_obj_t lv_obj_t;
/** /**
* Set relative the position of an object (relative to the parent) * Set relative the position of an object (relative to the parent)
* @param obj pointer to an object * @param obj pointer to an object
* @param x new distance from the left side of the parent * @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 of the parent * @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 to use grid placement the parent needs have a defined grid with `lv_obj_set_grid`
*/ */
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y); void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
/** /**
* Set the x coordinate of a object * Set the x coordinate of a object
* @param obj pointer to an object * @param obj pointer to an object
* @param x new distance from the left side from the parent * @param x new distance from the left side from the parent plus the parent's left padding or a grid cell
*/ */
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x); void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x);
/** /**
* Set the y coordinate of a object * Set the y coordinate of a object
* @param obj pointer to an object * @param obj pointer to an object
* @param y new distance from the top of the parent * @param y new distance from the top of the parent plus the parent's top padding or a grid cell
*/ */
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y); void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
void _lv_obj_calc_auto_size(lv_obj_t * obj, lv_coord_t * w, lv_coord_t * h);
/** /**
* Set the size of an object * Set the size of an object.
* @param obj pointer to an object * @param obj pointer to an object
* @param w new width * @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
* @param h new height * @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
*/ */
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h); void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
/** /**
* Set the width of an object * Set the width of an object
* @param obj pointer to an object * @param obj pointer to an object
* @param w new width * @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
*/ */
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w); void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w);
/** /**
* Set the height of an object * Set the height of an object
* @param obj pointer to an object * @param obj pointer to an object
* @param h new height * @param h new height in pixels or `LV_SIZE_AUTO` to set the size to involve all children
*/ */
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h); void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h);
/** /**
* Set the width reduced by the left and right padding. * Set the width reduced by the left and right padding.
* @param obj pointer to an object * @param obj pointer to an object
* @param w the width without paddings * @param w the width without paddings in pixels
*/ */
void lv_obj_set_content_width(lv_obj_t * obj, lv_coord_t w); void lv_obj_set_content_width(struct _lv_obj_t * obj, lv_coord_t w);
/** /**
* Set the height reduced by the top and bottom padding. * Set the height reduced by the top and bottom padding.
* @param obj pointer to an object * @param obj pointer to an object
* @param h the height without paddings * @param h the height without paddings in pixels
*/ */
void lv_obj_set_content_height(lv_obj_t * obj, lv_coord_t h); void lv_obj_set_content_height(struct _lv_obj_t * obj, lv_coord_t h);
/** /**
* Set the width of an object by taking the left and right margin into account. * Set the width of an object by taking the left and right margin into account.
* The object width will be `obj_w = w - margin_left - margin_right` * The object width will be `obj_w = w - margin_left - margin_right`
* @param obj pointer to an object * @param obj pointer to an object
* @param w new height including margins * @param w new height including margins in pixels
*/ */
void lv_obj_set_width_margin(lv_obj_t * obj, lv_coord_t w); void lv_obj_set_width_margin(struct _lv_obj_t * obj, lv_coord_t w);
/** /**
* Set the height of an object by taking the top and bottom margin into account. * Set the height of an object by taking the top and bottom margin into account.
* The object height will be `obj_h = h - margin_top - margin_bottom` * The object height will be `obj_h = h - margin_top - margin_bottom`
* @param obj pointer to an object * @param obj pointer to an object
* @param h new height including margins * @param h new height including margins in pixels
*/ */
void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h); void lv_obj_set_height_margin(struct _lv_obj_t * obj, lv_coord_t h);
/** /**
* Align an object to an other object. * Align an object to an other object.
@ -116,120 +116,120 @@ void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h);
* @param x_ofs x coordinate offset after alignment * @param x_ofs x coordinate offset after alignment
* @param y_ofs y coordinate offset after alignment * @param y_ofs y coordinate offset after alignment
*/ */
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(struct _lv_obj_t * obj, const struct _lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
/** /**
* Copy the coordinates of an object to an area * Copy the coordinates of an object to an area
* @param obj pointer to an object * @param obj pointer to an object
* @param cords_p pointer to an area to store the coordinates * @param coords_out pointer to an area to store the coordinates
*/ */
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p); void lv_obj_get_coords(const struct _lv_obj_t * obj, lv_area_t * coords_out);
/** /**
* Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object. * Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.
* (Without the size of the border or other extra graphical elements) * (Without the size of the border or other extra graphical elements)
* @param coords_p store the result area here * @param coords_out store the result area here
*/ */
void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p); void lv_obj_get_inner_coords(const struct _lv_obj_t * obj, lv_area_t * coords_out);
/** /**
* Get the x coordinate of object * Get the x coordinate of object.
* @param obj pointer to an object * @param obj pointer to an object
* @return distance of 'obj' from the left side of its parent * @return distance of 'obj' from the left side of its parent plus the parent's left padding
* @note Zero return value means the object is on the left padding of the parent, and not on the left edge.
* @note Scrolling of the parent doesn't change the returned value.
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
*/ */
lv_coord_t lv_obj_get_x(const lv_obj_t * obj); lv_coord_t lv_obj_get_x(const struct _lv_obj_t * obj);
/** /**
* Get the y coordinate of object * Get the y coordinate of object.
* @param obj pointer to an object * @param obj pointer to an object
* @return distance of 'obj' from the top of its parent * @return distance of 'obj' from the top side of its parent plus the parent's top padding
* @note Zero return value means the object is on the top padding of the parent, and not on the top edge.
* @note Scrolling of the parent doesn't change the returned value.
* @note The returned value is always the distance from the parent even if the position is grid cell or other special value.
*/ */
lv_coord_t lv_obj_get_y(const lv_obj_t * obj); lv_coord_t lv_obj_get_y(const struct _lv_obj_t * obj);
/** /**
* Get the width of an object * Get the width of an object
* @param obj pointer to an object * @param obj pointer to an object
* @return the width * @return the width in pixels
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
*/ */
lv_coord_t lv_obj_get_width(const lv_obj_t * obj); lv_coord_t lv_obj_get_width(const struct _lv_obj_t * obj);
/** /**
* Get the height of an object * Get the height of an object
* @param obj pointer to an object * @param obj pointer to an object
* @return the height * @return the height in pixels
* @note The returned value is always the width in pixels even if the width is set to `LV_SIZE_AUTO` or other special value.
*/ */
lv_coord_t lv_obj_get_height(const lv_obj_t * obj); lv_coord_t lv_obj_get_height(const struct _lv_obj_t * obj);
/** /**
* Get that width reduced by the left and right padding. * Get that width reduced by the left and right padding.
* @param obj pointer to an object * @param obj pointer to an object
* @return the width which still fits into the container * @return the width which still fits into the container without causing overflow
*/ */
lv_coord_t lv_obj_get_width_fit(const lv_obj_t * obj); lv_coord_t lv_obj_get_width_fit(const struct _lv_obj_t * obj);
/** /**
* Get that height reduced by the top an bottom padding. * Get that height reduced by the top an bottom padding.
* @param obj pointer to an object * @param obj pointer to an object
* @return the height which still fits into the container * @return the height which still fits into the container without causing overflow
*/ */
lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj); lv_coord_t lv_obj_get_height_fit(const struct _lv_obj_t * obj);
/** /**
* Get the height of an object by taking the top and bottom margin into account. * Get the height of an object by taking the top and bottom margin into account.
* The returned height will be `obj_h + margin_top + margin_bottom` * The returned height will be `obj_h + margin_top + margin_bottom`
* @param obj pointer to an object * @param obj pointer to an object
* @return the height including thee margins * @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(struct _lv_obj_t * obj);
/** /**
* Get the width of an object by taking the left and right margin into account. * Get the width of an object by taking the left and right margin into account.
* The returned width will be `obj_w + margin_left + margin_right` * The returned width will be `obj_w + margin_left + margin_right`
* @param obj pointer to an object * @param obj pointer to an object
* @return the height including thee margins * @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(struct _lv_obj_t * obj);
/** /**
* Check if a given screen-space point is on an object's coordinates. * Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
*
* This method is intended to be used mainly by advanced hit testing algorithms to check
* whether the point is even within the object (as an optimization).
* @param obj object to check
* @param point screen-space point
*/
bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point);
/**
* Divide the width of the object and get the width of a given number of columns.
* Take paddings into account.
* @param obj pointer to an object * @param obj pointer to an object
* @param div indicates how many columns are assumed. * @param w_out store the width here. NULL to not calculate width
* If 1 the width will be set the the parent's width * @param h_out store the height here. NULL to not calculate height
* If 2 only half parent width - inner padding of the parent
* If 3 only third parent width - 2 * inner padding of the parent
* @param span how many columns are combined
* @return the width according to the given parameters
*/ */
lv_coord_t lv_obj_get_width_grid(lv_obj_t * obj, uint8_t div, uint8_t span); void _lv_obj_calc_auto_size(struct _lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out);
/** /**
* Divide the height of the object and get the width of a given number of columns. * Move an object to a given x and y coordinate.
* Take paddings into account. * It's the core function to move objects but user should use `lv_obj_set_pos/x/y/..` etc.
* @param obj pointer to an object * @param obj pointer to an object to move
* @param div indicates how many rows are assumed. * @param x the new x coordinate in pixels
* If 1 the height will be set the the parent's height * @param y the new y coordinate in pixels
* If 2 only half parent height - inner padding of the parent * @param notify_parent true: send `LV_SIGNAL_CHILD_CHG` to the parent if `obj` moved; false: do not notify the parent
* If 3 only third parent height - 2 * inner padding of the parent
* @param span how many rows are combined
* @return the height according to the given parameters
*/ */
lv_coord_t lv_obj_get_height_grid(lv_obj_t * obj, uint8_t div, uint8_t span); void _lv_obj_move_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_parent);
void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_parent); /**
* Reposition the children of an object. (Called recursively)
* @param obj pointer to an object which children will be repositioned
* @param x_diff x coordinate shift
* @param y_diff y coordinate shift
*/
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);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -12,6 +12,7 @@
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define LV_OBJX_NAME "lv_obj"
#define SCROLL_ANIM_TIME_MIN 100 /*ms*/ #define SCROLL_ANIM_TIME_MIN 100 /*ms*/
#define SCROLL_ANIM_TIME_MAX 300 /*ms*/ #define SCROLL_ANIM_TIME_MAX 300 /*ms*/

View File

@ -25,7 +25,6 @@ extern "C" {
**********************/ **********************/
struct _lv_obj_t; struct _lv_obj_t;
typedef struct _lv_obj_t lv_obj_t;
/** Scrollbar modes: shows when should the scrollbars be visible*/ /** Scrollbar modes: shows when should the scrollbars be visible*/
enum { enum {
@ -54,14 +53,14 @@ typedef uint8_t lv_scroll_snap_align_t;
* @param obj pointer to an object * @param obj pointer to an object
* @param mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE * @param mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE
*/ */
void lv_obj_set_scroll_mode(lv_obj_t * obj, lv_scroll_mode_t mode); void lv_obj_set_scroll_mode(struct _lv_obj_t * obj, lv_scroll_mode_t mode);
/** /**
* Get how the scrollbars should behave. * Get how the scrollbars should behave.
* @param obj pointer to an object * @param obj pointer to an object
* @return mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE * @return mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE
*/ */
lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj); lv_scroll_mode_t lv_obj_get_scroll_mode(struct _lv_obj_t * obj);
/** /**
* Moves all children with horizontally or vertically. * Moves all children with horizontally or vertically.
@ -70,7 +69,7 @@ lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj);
* @param x pixel to move horizontally * @param x pixel to move horizontally
* @param y pixels to move vertically * @param y pixels to move vertically
*/ */
void _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y); void _lv_obj_scroll_by_raw(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
/** /**
* Moves all children with horizontally or vertically. * Moves all children with horizontally or vertically.
@ -79,7 +78,7 @@ void _lv_obj_scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
* @param x pixel to move horizontally * @param x pixel to move horizontally
* @param y pixels to move vertically * @param y pixels to move vertically
*/ */
void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en); void lv_obj_scroll_by(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
/** /**
* Scroll the a given x coordinate to the left side of obj. * Scroll the a given x coordinate to the left side of obj.
@ -87,21 +86,21 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable
* @param x the x coordinate to scroll to * @param x the x coordinate to scroll to
* @param y the y coordinate to scroll to * @param y the y coordinate to scroll to
*/ */
void lv_obj_scroll_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en); void lv_obj_scroll_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim_en);
/** /**
* Scroll the a given x coordinate to the left side of obj. * Scroll the a given x coordinate to the left side of obj.
* @param obj pointer to an object which should be scrolled * @param obj pointer to an object which should be scrolled
* @param x the x coordinate to scroll to * @param x the x coordinate to scroll to
*/ */
void lv_obj_scroll_to_x(lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en); void lv_obj_scroll_to_x(struct _lv_obj_t * obj, lv_coord_t x, lv_anim_enable_t anim_en);
/** /**
* Scroll the a given y coordinate to the top side of obj. * Scroll the a given y coordinate to the top side of obj.
* @param obj pointer to an object which should be scrolled * @param obj pointer to an object which should be scrolled
* @param y the y coordinate to scroll to * @param y the y coordinate to scroll to
*/ */
void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en); void lv_obj_scroll_to_y(struct _lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
/** /**
@ -111,7 +110,7 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en);
* @param obj * @param obj
* @return * @return
*/ */
lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj); lv_coord_t lv_obj_get_scroll_top(const struct _lv_obj_t * obj);
/** /**
* Return the height of the area below the parent. * Return the height of the area below the parent.
@ -120,7 +119,7 @@ lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj);
* @param obj * @param obj
* @return * @return
*/ */
lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj); lv_coord_t lv_obj_get_scroll_bottom(const struct _lv_obj_t * obj);
/** /**
@ -130,7 +129,7 @@ lv_coord_t lv_obj_get_scroll_bottom(const lv_obj_t * obj);
* @param obj * @param obj
* @return * @return
*/ */
lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj); lv_coord_t lv_obj_get_scroll_left(const struct _lv_obj_t * obj);
/** /**
* Return the width of the area below the object. * Return the width of the area below the object.
@ -139,7 +138,7 @@ lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj);
* @param obj * @param obj
* @return * @return
*/ */
lv_coord_t lv_obj_get_scroll_right(const lv_obj_t * obj); lv_coord_t lv_obj_get_scroll_right(const struct _lv_obj_t * obj);
/********************** /**********************

View File

@ -18,6 +18,7 @@
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define LV_OBJX_NAME "lv_obj"
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -53,10 +54,12 @@ static void trans_anim_start_cb(lv_anim_t * a);
static void trans_anim_ready_cb(lv_anim_t * a); static void trans_anim_ready_cb(lv_anim_t * a);
#endif #endif
#if LV_STYLE_CACHE_LEVEL >= 1
static bool style_prop_is_cacheable(lv_style_property_t prop); static bool style_prop_is_cacheable(lv_style_property_t prop);
static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop); static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop);
static void update_style_cache_children(lv_obj_t * obj); static void update_style_cache_children(lv_obj_t * obj);
static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop); static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop);
#endif
static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v); static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v);
static void fade_in_anim_ready(lv_anim_t * a); static void fade_in_anim_ready(lv_anim_t * a);
@ -251,6 +254,7 @@ lv_style_list_t * _lv_obj_get_style_list(const lv_obj_t * obj, uint8_t part)
*/ */
void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis) void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis)
{ {
#if LV_STYLE_CACHE_LEVEL >= 1
uint8_t part; uint8_t part;
for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) {
lv_style_list_t * list = _lv_obj_get_style_list(obj, part); lv_style_list_t * list = _lv_obj_get_style_list(obj, part);
@ -262,6 +266,10 @@ void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis)
if(list == NULL) break; if(list == NULL) break;
list->ignore_cache = dis; list->ignore_cache = dis;
} }
#else
LV_UNUSED(obj);
LV_UNUSED(dis);
#endif
} }
@ -291,14 +299,12 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl
const lv_obj_t * parent = obj; const lv_obj_t * parent = obj;
while(parent) { while(parent) {
lv_style_list_t * list = _lv_obj_get_style_list(parent, part); lv_style_list_t * list = _lv_obj_get_style_list(parent, part);
#if LV_STYLE_CACHE_LEVEL >= 1
if(!list->ignore_cache && list->style_cnt > 0) { if(!list->ignore_cache && list->style_cnt > 0) {
if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
bool def = false; bool def = false;
switch(prop & (~LV_STYLE_STATE_MASK)) { switch(prop & (~LV_STYLE_STATE_MASK)) {
case LV_STYLE_BG_GRAD_DIR:
if(list->bg_grad_dir_none) def = true;
break;
case LV_STYLE_CLIP_CORNER: case LV_STYLE_CLIP_CORNER:
if(list->clip_corner_off) def = true; if(list->clip_corner_off) def = true;
break; break;
@ -331,8 +337,16 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl
if(list->shadow_width_zero) def = true; if(list->shadow_width_zero) def = true;
break; break;
case LV_STYLE_PAD_TOP: case LV_STYLE_PAD_TOP:
if(list->pad_all_zero) def = true;
else if(list->pad_top) return list->pad_top;
break;
case LV_STYLE_PAD_BOTTOM: case LV_STYLE_PAD_BOTTOM:
if(list->pad_all_zero) def = true;
break;
case LV_STYLE_PAD_LEFT: case LV_STYLE_PAD_LEFT:
if(list->pad_all_zero) def = true;
else if(list->pad_left) return list->pad_left;
break;
case LV_STYLE_PAD_RIGHT: case LV_STYLE_PAD_RIGHT:
if(list->pad_all_zero) def = true; if(list->pad_all_zero) def = true;
break; break;
@ -359,6 +373,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl
break; break;
} }
} }
#endif
lv_state_t state = lv_obj_get_state(parent, part); lv_state_t state = lv_obj_get_state(parent, part);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
@ -480,7 +495,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop
const lv_obj_t * parent = obj; const lv_obj_t * parent = obj;
while(parent) { while(parent) {
lv_style_list_t * list = _lv_obj_get_style_list(parent, part); lv_style_list_t * list = _lv_obj_get_style_list(parent, part);
#if LV_STYLE_CACHE_LEVEL >= 1
if(!list->ignore_cache && list->style_cnt > 0) { if(!list->ignore_cache && list->style_cnt > 0) {
if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
bool def = false; bool def = false;
@ -501,7 +516,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop
break; break;
} }
} }
#endif
lv_state_t state = lv_obj_get_state(parent, part); lv_state_t state = lv_obj_get_state(parent, part);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
@ -559,7 +574,7 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_
const lv_obj_t * parent = obj; const lv_obj_t * parent = obj;
while(parent) { while(parent) {
lv_style_list_t * list = _lv_obj_get_style_list(parent, part); lv_style_list_t * list = _lv_obj_get_style_list(parent, part);
#if LV_STYLE_CACHE_LEVEL >= 1
if(!list->ignore_cache && list->style_cnt > 0) { if(!list->ignore_cache && list->style_cnt > 0) {
if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
bool def = false; bool def = false;
@ -579,7 +594,7 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_
break; break;
} }
} }
#endif
lv_state_t state = lv_obj_get_state(parent, part); lv_state_t state = lv_obj_get_state(parent, part);
prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS);
@ -748,8 +763,9 @@ void _lv_obj_reset_style_list_no_refr(lv_obj_t * obj, uint8_t part)
void _lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) void _lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_STYLE_CACHE_LEVEL >= 1
invalidate_style_cache(obj, part, prop); invalidate_style_cache(obj, part, prop);
#endif
/*If a real style refresh is required*/ /*If a real style refresh is required*/
bool real_refr = false; bool real_refr = false;
@ -1145,12 +1161,12 @@ static void trans_anim_ready_cb(lv_anim_t * a)
#endif #endif
#if LV_STYLE_CACHE_LEVEL >= 1
static bool style_prop_is_cacheable(lv_style_property_t prop) static bool style_prop_is_cacheable(lv_style_property_t prop)
{ {
switch(prop) { switch(prop) {
case LV_STYLE_PROP_ALL: case LV_STYLE_PROP_ALL:
case LV_STYLE_BG_GRAD_DIR:
case LV_STYLE_CLIP_CORNER: case LV_STYLE_CLIP_CORNER:
case LV_STYLE_TEXT_LETTER_SPACE: case LV_STYLE_TEXT_LETTER_SPACE:
case LV_STYLE_TEXT_LINE_SPACE: case LV_STYLE_TEXT_LINE_SPACE:
@ -1228,7 +1244,6 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop)
list->bg_opa_transp = bg_opa == LV_OPA_TRANSP ? 1 : 0; list->bg_opa_transp = bg_opa == LV_OPA_TRANSP ? 1 : 0;
list->bg_opa_cover = bg_opa == LV_OPA_COVER ? 1 : 0; list->bg_opa_cover = bg_opa == LV_OPA_COVER ? 1 : 0;
list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0;
list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0;
list->border_side_full = lv_obj_get_style_border_side(obj, part) == LV_BORDER_SIDE_FULL ? 1 : 0; list->border_side_full = lv_obj_get_style_border_side(obj, part) == LV_BORDER_SIDE_FULL ? 1 : 0;
list->border_post_off = lv_obj_get_style_border_post(obj, part) == 0 ? 1 : 0; list->border_post_off = lv_obj_get_style_border_post(obj, part) == 0 ? 1 : 0;
@ -1250,8 +1265,16 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop)
} }
list->pad_all_zero = 1; list->pad_all_zero = 1;
if(lv_obj_get_style_pad_top(obj, part) != 0 || lv_style_int_t pad_top = lv_obj_get_style_pad_top(obj, part);
lv_obj_get_style_pad_bottom(obj, part) != 0 || lv_style_int_t pad_left = lv_obj_get_style_pad_left(obj, part);
#if LV_STYLE_CACHE_LEVEL >= 2
list->pad_top = 0;
list->pad_left = 0;
if(pad_top > 0 && pad_top <= _LV_STLYE_CAHCE_INT_MAX) list->pad_top = pad_top;
if(pad_left > 0 && pad_left <= _LV_STLYE_CAHCE_INT_MAX) list->pad_left = pad_left;
#endif
if(pad_top != 0 ||
pad_left != 0 ||
lv_obj_get_style_pad_left(obj, part) != 0 || lv_obj_get_style_pad_left(obj, part) != 0 ||
lv_obj_get_style_pad_right(obj, part) != 0) { lv_obj_get_style_pad_right(obj, part) != 0) {
list->pad_all_zero = 0; list->pad_all_zero = 0;
@ -1354,6 +1377,8 @@ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_proper
child = lv_obj_get_child(obj, child); child = lv_obj_get_child(obj, child);
} }
} }
#endif /*LV_STYLE_CACHE_LEVEL >= 1*/
static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v) static void fade_anim_cb(lv_obj_t * obj, lv_anim_value_t v)
{ {

View File

@ -1070,9 +1070,9 @@ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t
stat[prop & 0xFF]++; stat[prop & 0xFF]++;
// //
// if((prop & 0xFF) == LV_STYLE_PAD_TOP) { if((prop & 0xFF) == LV_STYLE_PAD_TOP) {
// printf("pad top\n"); // printf("pad top\n");
// } }
uint8_t prop_id; uint8_t prop_id;
while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) { while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSEING_PROP) {

View File

@ -45,6 +45,10 @@ LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
#define LV_STYLE_PROP_ALL 0xFF #define LV_STYLE_PROP_ALL 0xFF
#if LV_STYLE_CACHE_LEVEL >= 2
#define _LV_STLYE_CAHCE_INT_MAX 63
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -236,9 +240,12 @@ typedef struct {
uint32_t has_trans : 1; uint32_t has_trans : 1;
uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/
uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/ uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/
#if LV_STYLE_CACHE_LEVEL >= 1
uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/ uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/
uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/ uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/
/*32 properties*/
uint32_t radius_zero : 1; uint32_t radius_zero : 1;
uint32_t opa_scale_cover : 1; uint32_t opa_scale_cover : 1;
uint32_t clip_corner_off : 1; uint32_t clip_corner_off : 1;
@ -248,7 +255,6 @@ typedef struct {
uint32_t blend_mode_all_normal : 1; uint32_t blend_mode_all_normal : 1;
uint32_t bg_opa_transp : 1; uint32_t bg_opa_transp : 1;
uint32_t bg_opa_cover : 1; uint32_t bg_opa_cover : 1;
uint32_t bg_grad_dir_none : 1;
uint32_t border_width_zero : 1; uint32_t border_width_zero : 1;
uint32_t border_side_full : 1; uint32_t border_side_full : 1;
@ -263,6 +269,13 @@ typedef struct {
uint32_t text_space_zero : 1; uint32_t text_space_zero : 1;
uint32_t text_decor_none : 1; uint32_t text_decor_none : 1;
uint32_t text_font_normal : 1; uint32_t text_font_normal : 1;
#endif
#if LV_STYLE_CACHE_LEVEL >= 2
uint32_t pad_top :6;
uint32_t pad_left :6;
#endif
} lv_style_list_t; } lv_style_list_t;
/********************** /**********************

View File

@ -1163,7 +1163,7 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param
/* Include the ancient signal function */ /* Include the ancient signal function */
res = ancestor_signal(label, sign, param); res = ancestor_signal(label, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_label_ext_t * ext = lv_obj_get_ext_attr(label); lv_label_ext_t * ext = lv_obj_get_ext_attr(label);
if(sign == LV_SIGNAL_CLEANUP) { if(sign == LV_SIGNAL_CLEANUP) {