diff --git a/src/lv_core/lv_core.mk b/src/lv_core/lv_core.mk index 9f15199bd..fab150b13 100644 --- a/src/lv_core/lv_core.mk +++ b/src/lv_core/lv_core.mk @@ -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 diff --git a/src/lv_core/lv_grid.c b/src/lv_core/lv_grid.c index 3c8fcd820..c68a649a3 100644 --- a/src/lv_core/lv_grid.c +++ b/src/lv_core/lv_grid.c @@ -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); +} diff --git a/src/lv_core/lv_grid.h b/src/lv_core/lv_grid.h index 846ca718a..9fef06cdf 100644 --- a/src/lv_core/lv_grid.h +++ b/src/lv_core/lv_grid.h @@ -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); diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 50ad967df..565eb020f 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -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 diff --git a/src/lv_core/lv_indev_scroll.c b/src/lv_core/lv_indev_scroll.c index fa0fcfc89..d8f859203 100644 --- a/src/lv_core/lv_indev_scroll.c +++ b/src/lv_core/lv_indev_scroll.c @@ -1,5 +1,5 @@ /** - * @file lv_scroll.c + * @file lv_indev_scroll.c * */ diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index caeecc90d..3ce1e7951 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -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, ©->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); - } -} - diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 7e99a647e..4fff3710b 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -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 diff --git a/src/lv_core/lv_obj_pos.c b/src/lv_core/lv_obj_pos.c index ec9c17dfe..247cb108e 100644 --- a/src/lv_core/lv_obj_pos.c +++ b/src/lv_core/lv_obj_pos.c @@ -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*/ diff --git a/src/lv_core/lv_obj_pos.h b/src/lv_core/lv_obj_pos.h index d7363c5e4..8dd4d94d2 100644 --- a/src/lv_core/lv_obj_pos.h +++ b/src/lv_core/lv_obj_pos.h @@ -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 **********************/ diff --git a/src/lv_core/lv_obj_scroll.c b/src/lv_core/lv_obj_scroll.c index 4d94a5ba0..83ce66cce 100644 --- a/src/lv_core/lv_obj_scroll.c +++ b/src/lv_core/lv_obj_scroll.c @@ -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*/ diff --git a/src/lv_core/lv_obj_scroll.h b/src/lv_core/lv_obj_scroll.h index fa5ab753d..bb7987132 100644 --- a/src/lv_core/lv_obj_scroll.h +++ b/src/lv_core/lv_obj_scroll.h @@ -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); /********************** diff --git a/src/lv_core/lv_obj_style.c b/src/lv_core/lv_obj_style.c index 9fa0be8b9..54355189d 100644 --- a/src/lv_core/lv_obj_style.c +++ b/src/lv_core/lv_obj_style.c @@ -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) { diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 5fc116932..5841206b0 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -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) { diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index c992388c0..9d2954569 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -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; /********************** diff --git a/src/lv_widgets/lv_label.c b/src/lv_widgets/lv_label.c index cfb74e16e..8dd5d84e8 100644 --- a/src/lv_widgets/lv_label.c +++ b/src/lv_widgets/lv_label.c @@ -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) {