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_group.c
CSRCS += lv_indev.c
CSRCS += lv_indev_scroll.c
CSRCS += lv_disp.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_style.c

View File

@ -17,6 +17,11 @@
/**********************
* TYPEDEFS
**********************/
typedef struct {
uint32_t col;
uint32_t row;
lv_point_t grid_abs;
}item_repos_hint_t;
/**********************
* 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_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 item_repos(lv_obj_t * cont, lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint);
/**********************
* STATIC VARIABLES
@ -42,36 +48,47 @@ static bool row_dsc_buf_used;
* 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;
// static uint32_t cnt = 0;
// cnt++;
// printf("calc: %d (size: %d)\n", cnt, obj->grid->col_dsc_len);
// printf("calc: %d, %d\n", obj->grid->col_dsc_len, obj->grid->row_dsc_len);
if(obj->grid->col_dsc && obj->grid->row_dsc) {
calc_explicit_rows(obj, calc);
calc_explicit_cols(obj, calc);
calc_explicit_rows(obj, calc_out);
calc_explicit_cols(obj, calc_out);
}
else if(obj->grid->col_dsc && !obj->grid->row_dsc) {
calc_explicit_cols(obj, calc);
calc_implicit_rows(obj, calc);
calc_explicit_cols(obj, calc_out);
calc_implicit_rows(obj, calc_out);
}
else if(!obj->grid->col_dsc && obj->grid->row_dsc) {
calc_implicit_cols(obj, calc);
calc_explicit_rows(obj, calc);
calc_implicit_cols(obj, calc_out);
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->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)
{
if(obj->grid == NULL) return false;
@ -85,6 +102,11 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
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)
{
if(obj->grid == NULL) return false;
@ -98,164 +120,58 @@ bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
return false;
}
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)
{
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;
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)
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
*/
void _lv_grid_full_refresh(lv_obj_t * cont)
{
/*Calculate the grid*/
if(cont->grid == NULL) return;
_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.
* 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_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);
grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_top(cont);
hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_left(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);
while(item) {
if(_GRID_IS_CELL(item->x_set) && _GRID_IS_CELL(item->y_set)) {
_grid_item_repos(cont, item, &calc, &child_id, &grid_abs);
child_id++;
item_repos(cont, item, &calc, &hint);
}
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) {
lv_obj_set_size(cont, cont->w_set, cont->h_set);
}
}
/**
* Refresh the position of a grid item
* @param item pointer to a grid item
*/
void lv_grid_item_refr_pos(lv_obj_t * item)
{
/*Calculate the grid*/
lv_obj_t * cont = lv_obj_get_parent(item);
if(cont == NULL) return;
if(cont->grid == NULL) return;
_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;
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 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_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);

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;
/*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_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)
{
/*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 &&
proc->types.pointer.last_pressed != obj_to_focus) {
#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_OBJ_DEF_WIDTH (LV_DPX(100))
#define LV_OBJ_DEF_HEIGHT (LV_DPX(50))
#define SCROLLBAR_MIN_SIZE (LV_DPX(10))
#define GRID_DEBUG 1 /*Draw rectangles on grid cells*/
#define GRID_DEBUG 0 /*Draw rectangles on grid cells*/
/**********************
* 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 void lv_obj_del_async_cb(void * 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);
/**********************
@ -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
_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
new_obj->ext_click_pad_hor = 0;
new_obj->ext_click_pad_ver = 0;
new_obj->ext_click_pad = 0;
#endif
/*Init. user date*/
@ -286,7 +282,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
#endif
/*Set attributes*/
new_obj->adv_hittest = 0;
new_obj->scroll_mode = LV_SCROLL_MODE_AUTO;
new_obj->scroll_dir = LV_DIR_ALL;
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
lv_area_copy(&new_obj->ext_click_pad, &copy->ext_click_pad);
#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_ver = copy->ext_click_pad_ver;
new_obj->ext_click_pad = copy->ext_click_pad;
#endif
/*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;
/*Copy attributes*/
new_obj->adv_hittest = copy->adv_hittest;
new_obj->flags = copy->flags;
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.y2 = bottom;
#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_ver = LV_MATH_MAX(top, bottom);
obj->ext_click_pad = LV_MATH_MAX4(left, right, top, bottom);
#else
(void)obj; /*Unused*/
(void)left; /*Unused*/
(void)right; /*Unused*/
(void)top; /*Unused*/
(void)bottom; /*Unused*/
LV_UNUSED(obj);
LV_UNUSED(left);
LV_UNUSED(right);
LV_UNUSED(top);
LV_UNUSED(bottom);
#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
*----------------*/
/**
* 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
* @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;
}
/**
* 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
@ -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 dir in which direction get the extended area (`LV_DIR_LEFT/RIGHT/TOP`)
* @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
return obj->ext_click_pad_hor;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
return obj->ext_click_pad.x1;
#else
(void)obj; /*Unused*/
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_OFF
LV_UNUSED(obj);
LV_UNUSED(dir);
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
}
/**
* 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
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
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
(void)obj; /*Unused*/
return 0;
if(!_lv_area_is_point_on(&obj->coords, point, 0)) {
#endif
return false;
}
return true;
}
/**
* Get the top padding of extended clickable area
* @param obj pointer to an object
* @return the extended top padding
* 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
*/
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_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.y1;
#else
(void)obj; /*Unused*/
return 0;
#endif
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_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_click_point_on(obj, 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)
{
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
*---------------*/
@ -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;
}
/**
* 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_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
* @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;
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;
}
/**
* 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
* @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)
* @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;
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;
}
/**
* 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
@ -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")
* @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;
@ -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")
* @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);
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) {
scrollbar_draw(obj, clip_area);
_lv_obj_draw_scrollbar(obj, clip_area);
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);
@ -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*/
if(obj->grid) {
_lv_grid_calc_t calc;
grid_calc(obj, &calc);
_lv_grid_calc(obj, &calc);
/*Create a color unique to this object. */
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
}
@ -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;
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;
@ -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)) ||
(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) {
@ -2208,9 +1830,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(obj->grid) {
lv_obj_t * child = param;
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 {
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) {
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);
}
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);
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) {
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) {
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;
/*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);
}
else {
/*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_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) {
/*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);
}
@ -2314,168 +1935,3 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin
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;
/** Design modes */
enum {
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_GESTURE_BUBBLE = (1 << 8),
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 9),
LV_OBJ_FLAG_ADV_HITTEST = (1 << 10),
};
typedef uint16_t lv_obj_flag_t;
#include "lv_obj_pos.h"
#include "lv_obj_scroll.h"
#include "lv_obj_style.h"
#include "lv_obj_draw.h"
typedef struct _lv_obj_t {
@ -219,8 +221,7 @@ typedef struct _lv_obj_t {
lv_style_list_t style_list;
#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_ver; /**< Extra click padding in vertical direction */
uint8_t ext_click_pad; /**< Extra click padding in all direction */
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
lv_area_t ext_click_pad; /**< Extra click padding area. */
#endif
@ -228,13 +229,12 @@ typedef struct _lv_obj_t {
lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */
/*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_snap_align_t snap_align_x : 2;
lv_scroll_snap_align_t snap_align_y : 2;
lv_scroll_dir_t scroll_dir :4;
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;
@ -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
*----------------*/
/**
* 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
* @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_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);
/**
@ -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);
/**
* Send an event to the 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);
/**
* 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
*======================*/
@ -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 dir in which direction get the extended area (`LV_DIR_LEFT/RIGHT/TOP`)
* @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
* @param obj pointer to an object
* @return the extended right padding
* 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
*/
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
* @param obj pointer to an object
* @return the extended top padding
* 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
*/
lv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj);
/**
* 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
*---------------*/
bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/*-----------------
* Attribute get
*----------------*/
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_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
*-----------------*/
/**
* 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.
* @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);
bool lv_obj_hit_test(lv_obj_t * obj, lv_point_t * point);
/**
* Get the ext pointer
@ -786,7 +740,7 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
* @param obj the start object
* @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
@ -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)
* @return LV_RES_OK
*/
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);
lv_res_t _lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
/**
@ -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")
* @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
@ -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")
* @return true: valid
*/
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"
bool _lv_debug_check_obj_valid(const lv_obj_t * obj);
/**********************
* 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
# 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_type(obj_p, obj_type))
_lv_debug_check_obj_valid(obj_p) && \
_lv_debug_check_obj_type(obj_p, obj_type))
# endif

View File

@ -11,6 +11,7 @@
/*********************
* DEFINES
*********************/
#define LV_OBJX_NAME "lv_obj"
/**********************
* 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(!gi) {
if(_GRID_IS_CELL(x)) {
obj->x_set = 0;
x = 0;
}
if(_GRID_IS_CELL(y)) {
obj->y_set = 0;
y = 0;
}
}
// if(!gi) {
// if(_GRID_IS_CELL(x)) {
// obj->x_set = 0;
// x = 0;
// }
// if(_GRID_IS_CELL(y)) {
// obj->y_set = 0;
// y = 0;
// }
// }
/*If the object is on a grid item let the grid to position it. */
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);
/*If the item was moved and grid is implicit in the changed direction refresh the whole grid.*/
if((cont->grid->col_dsc == NULL && (old_area.x1 != obj->coords.x1 || old_area.x2 != obj->coords.x2)) ||
(cont->grid->row_dsc == NULL && (old_area.y1 != obj->coords.y1 || old_area.y2 != obj->coords.y2)))
/*If the item was moved on an implicit grid the whole grid can change so refresh the full grid.*/
if(cont->grid->col_dsc == NULL || cont->grid->row_dsc == NULL)
{
lv_grid_full_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 {
_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;
}
/**
* 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)`
* @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;
// printf("auto size\n");
/*If no other effect the auto-size of zero by default*/
if(w_out) *w_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;
if(obj->grid) {
_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_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*/

View File

@ -22,10 +22,7 @@ extern "C" {
/**********************
* TYPEDEFS
**********************/
/* Can't include lv_obj.h because it includes this header file */
struct _lv_obj_t;
typedef struct _lv_obj_t lv_obj_t;
/**********************
* 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)
* @param obj pointer to an object
* @param x new distance from the left side of the parent
* @param y new distance from the top 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 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
* @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
* @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_calc_auto_size(lv_obj_t * obj, lv_coord_t * w, lv_coord_t * h);
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
/**
* Set the size of an object
* Set the size of an object.
* @param obj pointer to an object
* @param w new width
* @param h new height
* @param w new width in pixels or `LV_SIZE_AUTO` to set the size to involve all children
* @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
* @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
* @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.
* @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.
* @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.
* The object width will be `obj_w = w - margin_left - margin_right`
* @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.
* The object height will be `obj_h = h - margin_top - margin_bottom`
* @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.
@ -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 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
* @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.
* (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
* @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
* @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
* @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
* @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.
* @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.
* @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.
* The returned height will be `obj_h + margin_top + margin_bottom`
* @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.
* The returned width will be `obj_w + margin_left + margin_right`
* @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.
*
* 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.
* Calculate the "auto size". It's `auto_size = max(gird_size, children_size)`
* @param obj pointer to an object
* @param div indicates how many columns are assumed.
* If 1 the width will be set the the parent's width
* 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
* @param w_out store the width here. NULL to not calculate width
* @param h_out store the height here. NULL to not calculate height
*/
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.
* Take paddings into account.
* @param obj pointer to an object
* @param div indicates how many rows are assumed.
* If 1 the height will be set the the parent's height
* If 2 only half parent height - inner padding of 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
* Move an object to a given x and y coordinate.
* 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 to move
* @param x the new x coordinate in pixels
* @param y the new y coordinate in pixels
* @param notify_parent true: send `LV_SIGNAL_CHILD_CHG` to the parent if `obj` moved; false: do not notify the parent
*/
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
**********************/

View File

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

View File

@ -25,7 +25,6 @@ extern "C" {
**********************/
struct _lv_obj_t;
typedef struct _lv_obj_t lv_obj_t;
/** Scrollbar modes: shows when should the scrollbars be visible*/
enum {
@ -54,14 +53,14 @@ typedef uint8_t lv_scroll_snap_align_t;
* @param obj pointer to an object
* @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.
* @param obj pointer to an object
* @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.
@ -70,7 +69,7 @@ lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj);
* @param x pixel to move horizontally
* @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.
@ -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 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.
@ -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 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.
* @param obj pointer to an object which should be scrolled
* @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.
* @param obj pointer to an object which should be scrolled
* @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
* @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.
@ -120,7 +119,7 @@ lv_coord_t lv_obj_get_scroll_top(const lv_obj_t * obj);
* @param obj
* @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
* @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.
@ -139,7 +138,7 @@ lv_coord_t lv_obj_get_scroll_left(const lv_obj_t * obj);
* @param obj
* @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
*********************/
#define LV_OBJX_NAME "lv_obj"
/**********************
* 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);
#endif
#if LV_STYLE_CACHE_LEVEL >= 1
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_children(lv_obj_t * obj);
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_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)
{
#if LV_STYLE_CACHE_LEVEL >= 1
uint8_t part;
for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; 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;
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;
while(parent) {
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->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
bool def = false;
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:
if(list->clip_corner_off) def = true;
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;
break;
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:
if(list->pad_all_zero) def = true;
break;
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:
if(list->pad_all_zero) def = true;
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;
}
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
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;
while(parent) {
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->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
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;
}
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
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;
while(parent) {
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->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK));
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;
}
}
#endif
lv_state_t state = lv_obj_get_state(parent, part);
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)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_STYLE_CACHE_LEVEL >= 1
invalidate_style_cache(obj, part, prop);
#endif
/*If a real style refresh is required*/
bool real_refr = false;
@ -1145,12 +1161,12 @@ static void trans_anim_ready_cb(lv_anim_t * a)
#endif
#if LV_STYLE_CACHE_LEVEL >= 1
static bool style_prop_is_cacheable(lv_style_property_t prop)
{
switch(prop) {
case LV_STYLE_PROP_ALL:
case LV_STYLE_BG_GRAD_DIR:
case LV_STYLE_CLIP_CORNER:
case LV_STYLE_TEXT_LETTER_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_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_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;
@ -1250,8 +1265,16 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop)
}
list->pad_all_zero = 1;
if(lv_obj_get_style_pad_top(obj, part) != 0 ||
lv_obj_get_style_pad_bottom(obj, part) != 0 ||
lv_style_int_t pad_top = lv_obj_get_style_pad_top(obj, part);
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_right(obj, part) != 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);
}
}
#endif /*LV_STYLE_CACHE_LEVEL >= 1*/
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]++;
//
// if((prop & 0xFF) == LV_STYLE_PAD_TOP) {
if((prop & 0xFF) == LV_STYLE_PAD_TOP) {
// printf("pad top\n");
// }
}
uint8_t prop_id;
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
#if LV_STYLE_CACHE_LEVEL >= 2
#define _LV_STLYE_CAHCE_INT_MAX 63
#endif
/**********************
* TYPEDEFS
**********************/
@ -236,9 +240,12 @@ typedef struct {
uint32_t has_trans : 1;
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*/
#if LV_STYLE_CACHE_LEVEL >= 1
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*/
/*32 properties*/
uint32_t radius_zero : 1;
uint32_t opa_scale_cover : 1;
uint32_t clip_corner_off : 1;
@ -248,7 +255,6 @@ typedef struct {
uint32_t blend_mode_all_normal : 1;
uint32_t bg_opa_transp : 1;
uint32_t bg_opa_cover : 1;
uint32_t bg_grad_dir_none : 1;
uint32_t border_width_zero : 1;
uint32_t border_side_full : 1;
@ -263,6 +269,13 @@ typedef struct {
uint32_t text_space_zero : 1;
uint32_t text_decor_none : 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;
/**********************

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 */
res = ancestor_signal(label, sign, param);
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);
if(sign == LV_SIGNAL_CLEANUP) {