diff --git a/src/lv_core/lv_indev_scroll.c b/src/lv_core/lv_indev_scroll.c index 2cedf81a7..11469f4e2 100644 --- a/src/lv_core/lv_indev_scroll.c +++ b/src/lv_core/lv_indev_scroll.c @@ -12,6 +12,7 @@ /********************* * DEFINES *********************/ +#define ELASTIC_SLOWNESS_FACTOR 4 /*Scrolling on elastic parts are slower by this factor*/ /********************** * TYPEDEFS @@ -26,6 +27,7 @@ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coo static void scroll_limit_diff(lv_indev_proc_t * proc, lv_coord_t * diff_x, lv_coord_t * diff_y); static lv_coord_t scroll_throw_predict_y(lv_indev_proc_t * proc); static lv_coord_t scroll_throw_predict_x(lv_indev_proc_t * proc); +static lv_coord_t elastic_diff(lv_obj_t * obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end); /********************** * STATIC VARIABLES @@ -219,16 +221,15 @@ void _lv_scroll_handler(lv_indev_proc_t * proc) lv_coord_t diff_y = 0; if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) { - diff_x = proc->types.pointer.vect.x; - if(lv_obj_get_scroll_right(scroll_obj) < 0) diff_x = diff_x / 2; - if(lv_obj_get_scroll_left(scroll_obj) < 0) diff_x = diff_x / 2; + lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); + lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); + diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr); } else { - diff_y = proc->types.pointer.vect.y; - if(lv_obj_get_scroll_top(scroll_obj) < 0) diff_y = diff_y / 2; - if(lv_obj_get_scroll_bottom(scroll_obj) < 0) diff_y = diff_y / 2; + lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); + lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); + diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb); } - if((scroll_obj->scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0; if((scroll_obj->scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0; if((scroll_obj->scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0; @@ -252,27 +253,28 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) { lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; if(scroll_obj == NULL) return; + if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) return; + lv_indev_t * indev_act = lv_indev_get_act(); lv_coord_t scroll_throw = indev_act->driver.scroll_throw; - if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) { - return; + if(lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_MOMENTUM) == false) { + proc->types.pointer.scroll_throw_vect.y = 0; + proc->types.pointer.scroll_throw_vect.x = 0; } - else if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_VER) { + + if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_VER) { proc->types.pointer.scroll_throw_vect.x = 0; /*If no snapping "throw"*/ if(scroll_obj->snap_align_y == LV_SCROLL_SNAP_ALIGN_NONE) { proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y * (100 - scroll_throw) / 100; - lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); + lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); - /*If scrolled inside reduce faster*/ - if(st < 0 || sb < 0) { - proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y >> 1; - } + proc->types.pointer.scroll_throw_vect.y = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.y, st, sb); _lv_obj_scroll_by_raw(scroll_obj, 0, proc->types.pointer.scroll_throw_vect.y); } @@ -295,10 +297,7 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); - /*If scrolled inside reduce faster*/ - if(sl < 0 || sr < 0) { - proc->types.pointer.scroll_throw_vect.x = proc->types.pointer.scroll_throw_vect.x >> 1; - } + proc->types.pointer.scroll_throw_vect.x = elastic_diff(scroll_obj, proc->types.pointer.scroll_throw_vect.x, sl ,sr); _lv_obj_scroll_by_raw(scroll_obj, proc->types.pointer.scroll_throw_vect.x, 0); } @@ -344,12 +343,13 @@ void _lv_scroll_throw_handler(lv_indev_proc_t * proc) } } - proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE; - proc->types.pointer.scroll_obj = NULL; lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_END, indev_act); if(proc->reset_query) return; lv_event_send(scroll_obj, LV_EVENT_SCROLL_END, indev_act); if(proc->reset_query) return; + + proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE; + proc->types.pointer.scroll_obj = NULL; } } @@ -531,3 +531,18 @@ static lv_coord_t scroll_throw_predict_x(lv_indev_proc_t * proc) return move; } +static lv_coord_t elastic_diff(lv_obj_t * obj, lv_coord_t diff, lv_coord_t scroll_start, lv_coord_t scroll_end) +{ + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLL_ELASTIC)) { + /*Elastic scroll if scrolled in*/ + if(scroll_end < 0) diff = (diff + ELASTIC_SLOWNESS_FACTOR / 2) / ELASTIC_SLOWNESS_FACTOR; + else if(scroll_start < 0) diff = (diff + ELASTIC_SLOWNESS_FACTOR / 2) / ELASTIC_SLOWNESS_FACTOR; + } else { + /*Scroll back to the boundary id required*/ + if(scroll_end + diff < 0) diff = - scroll_end; + if(scroll_start - diff < 0) diff = scroll_start; + } + + return diff; +} + diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8121d0011..595399dd0 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -289,6 +289,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->flags |= LV_OBJ_FLAG_PRESS_LOCK; new_obj->flags |= LV_OBJ_FLAG_CLICK_FOCUSABLE; new_obj->flags |= LV_OBJ_FLAG_SCROLLABLE; + new_obj->flags |= LV_OBJ_FLAG_SCROLL_ELASTIC; + new_obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM; if(parent) new_obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE; new_obj->state = LV_STATE_DEFAULT; new_obj->scroll.x = 0; diff --git a/src/lv_core/lv_obj_style.c b/src/lv_core/lv_obj_style.c index ceca453a0..16b4d49cb 100644 --- a/src/lv_core/lv_obj_style.c +++ b/src/lv_core/lv_obj_style.c @@ -438,6 +438,9 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_VALUE_BLEND_MODE: if(list->blend_mode_all_normal) def = true; break; + case LV_STYLE_TEXT_DECOR: + if(list->text_decor_none) def = true; + break; } if(def) { @@ -1346,6 +1349,7 @@ static bool style_prop_is_cacheable(lv_style_property_t prop) case LV_STYLE_TEXT_LETTER_SPACE: case LV_STYLE_TEXT_LINE_SPACE: case LV_STYLE_TEXT_FONT: + case LV_STYLE_TEXT_DECOR: case LV_STYLE_TRANSFORM_ANGLE: case LV_STYLE_TRANSFORM_WIDTH: case LV_STYLE_TRANSFORM_HEIGHT: diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index ba89955a6..7cde8370d 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -512,7 +512,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) font->line_height = font_header.ascent - font_header.descent; font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; - font->subpx = LV_FONT_SUBPX_NONE; + font->subpx = font_header.subpixels_mode; font_dsc->bpp = font_header.bits_per_pixel; font_dsc->kern_scale = font_header.kerning_scale; diff --git a/src/lv_widgets/lv_line.c b/src/lv_widgets/lv_line.c index c54a0ecf5..1d7ae5b92 100644 --- a/src/lv_widgets/lv_line.c +++ b/src/lv_widgets/lv_line.c @@ -71,7 +71,6 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) ext->point_num = 0; ext->point_array = NULL; - ext->auto_size = 1; ext->y_inv = 0; lv_obj_set_design_cb(line, lv_line_design); @@ -79,23 +78,19 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new line*/ if(copy == NULL) { - lv_obj_set_size(line, LV_DPI, - LV_DPI); /*Auto size is enables, but set default size until no points are added*/ - - lv_obj_set_click(line, false); + lv_obj_set_size(line, LV_SIZE_AUTO, LV_SIZE_AUTO); + lv_obj_clear_flag(line, LV_OBJ_FLAG_CLICKABLE); lv_theme_apply(line, LV_THEME_LINE); } /*Copy an existing object*/ else { lv_line_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - lv_line_set_auto_size(line, lv_line_get_auto_size(copy)); lv_line_set_y_invert(line, lv_line_get_y_invert(copy)); - lv_line_set_auto_size(line, lv_line_get_auto_size(copy)); lv_line_set_points(line, copy_ext->point_array, copy_ext->point_num); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); + _lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("line created"); @@ -122,41 +117,11 @@ void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t po ext->point_array = point_a; ext->point_num = point_num; - if(point_num > 0 && ext->auto_size != 0) { - uint16_t i; - lv_coord_t xmax = LV_COORD_MIN; - lv_coord_t ymax = LV_COORD_MIN; - for(i = 0; i < point_num; i++) { - xmax = LV_MATH_MAX(point_a[i].x, xmax); - ymax = LV_MATH_MAX(point_a[i].y, ymax); - } - - lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN); - lv_obj_set_size(line, xmax + line_width, ymax + line_width); - } + _lv_obj_handle_self_size_chg(line); lv_obj_invalidate(line); } -/** - * Enable (or disable) the auto-size option. The size of the object will fit to its points. - * (set width to x max and height to y max) - * @param line pointer to a line object - * @param en true: auto size is enabled, false: auto size is disabled - */ -void lv_line_set_auto_size(lv_obj_t * line, bool en) -{ - LV_ASSERT_OBJ(line, LV_OBJX_NAME); - - lv_line_ext_t * ext = lv_obj_get_ext_attr(line); - if(ext->auto_size == en) return; - - ext->auto_size = en == false ? 0 : 1; - - /*Refresh the object*/ - if(en) lv_line_set_points(line, ext->point_array, ext->point_num); -} - /** * Enable (or disable) the y coordinate inversion. * If enabled then y will be subtracted from the height of the object, @@ -180,20 +145,6 @@ void lv_line_set_y_invert(lv_obj_t * line, bool en) * Getter functions *====================*/ -/** - * Get the auto size attribute - * @param line pointer to a line object - * @return true: auto size is enabled, false: disabled - */ -bool lv_line_get_auto_size(const lv_obj_t * line) -{ - LV_ASSERT_OBJ(line, LV_OBJX_NAME); - - lv_line_ext_t * ext = lv_obj_get_ext_attr(line); - - return ext->auto_size == 0 ? false : true; -} - /** * Get the y inversion attribute * @param line pointer to a line object @@ -234,8 +185,8 @@ static lv_design_res_t lv_line_design(lv_obj_t * line, const lv_area_t * clip_ar lv_area_t area; lv_obj_get_coords(line, &area); - lv_coord_t x_ofs = area.x1; - lv_coord_t y_ofs = area.y1; + lv_coord_t x_ofs = area.x1 - lv_obj_get_scroll_top(line); + lv_coord_t y_ofs = area.y1 - lv_obj_get_scroll_left(line); lv_point_t p1; lv_point_t p2; lv_coord_t h = lv_obj_get_height(line); @@ -280,13 +231,34 @@ static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param) /* Include the ancient signal function */ res = ancestor_signal(line, 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_REFR_EXT_DRAW_PAD) { + if(sign == LV_SIGNAL_GET_TYPE) { + return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + } + else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { /*The corner of the skew lines is out of the intended area*/ lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN); if(line->ext_draw_pad < line_width) line->ext_draw_pad = line_width; } + else if(sign == LV_SIGNAL_GET_SELF_SIZE) { + lv_line_ext_t * ext = lv_obj_get_ext_attr(line); + + lv_point_t * p = param; + lv_coord_t w = 0; + lv_coord_t h = 0; + if(ext->point_num > 0) { + uint16_t i; + for(i = 0; i < ext->point_num; i++) { + w = LV_MATH_MAX(ext->point_array[i].x, w); + h = LV_MATH_MAX(ext->point_array[i].y, h); + } + + lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN); + w += line_width; + h += line_width; + p->x = w; + p->y = h; + } + } return res; } diff --git a/src/lv_widgets/lv_line.h b/src/lv_widgets/lv_line.h index 430a9da01..1ea0a2ad4 100644 --- a/src/lv_widgets/lv_line.h +++ b/src/lv_widgets/lv_line.h @@ -32,7 +32,6 @@ typedef struct { /*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/ const lv_point_t * point_array; /*Pointer to an array with the points of the line*/ uint16_t point_num; /*Number of points in 'point_array' */ - uint8_t auto_size : 1; /*1: set obj. width to x max and obj. height to y max */ uint8_t y_inv : 1; /*1: y == 0 will be on the bottom*/ } lv_line_ext_t; @@ -66,14 +65,6 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy); */ void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num); -/** - * Enable (or disable) the auto-size option. The size of the object will fit to its points. - * (set width to x max and height to y max) - * @param line pointer to a line object - * @param en true: auto size is enabled, false: auto size is disabled - */ -void lv_line_set_auto_size(lv_obj_t * line, bool en); - /** * Enable (or disable) the y coordinate inversion. * If enabled then y will be subtracted from the height of the object, @@ -92,13 +83,6 @@ work */ * Getter functions *====================*/ -/** - * Get the auto size attribute - * @param line pointer to a line object - * @return true: auto size is enabled, false: disabled - */ -bool lv_line_get_auto_size(const lv_obj_t * line); - /** * Get the y inversion attribute * @param line pointer to a line object diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index c79a64999..04e47a028 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -103,7 +103,8 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) ext->row_h[0] = LV_DPI; /*It will be overwritten when the theme is applied*/ ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char *)); - lv_obj_set_size(table, LV_SIZE_AUTO, 80); + lv_obj_set_size(table, 80, 80); +// lv_obj_set_size(table, LV_SIZE_AUTO, LV_SIZE_AUTO); lv_theme_apply(table, LV_THEME_TABLE); } @@ -710,6 +711,7 @@ static lv_design_res_t lv_table_design(lv_obj_t * table, const lv_area_t * clip_ uint16_t cell = 0; cell_area.y2 = table->coords.y1 + bg_top - 1 - lv_obj_get_scroll_top(table); + lv_coord_t scroll_left = lv_obj_get_scroll_left(table); for(row = 0; row < ext->row_cnt; row++) { lv_coord_t h_row = ext->row_h[row]; @@ -718,7 +720,7 @@ static lv_design_res_t lv_table_design(lv_obj_t * table, const lv_area_t * clip_ if(cell_area.y1 > clip_area->y2) return LV_DESIGN_RES_OK; - cell_area.x2 = table->coords.x1 + bg_left - 1; + cell_area.x2 = table->coords.x1 + bg_left - 1 - scroll_left; for(col = 0; col < ext->col_cnt; col++) {