1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

handle LV_OBJ_FLAG_SCROLL_ELASTIC/MOMENTUM

This commit is contained in:
Gabor Kiss-Vamosi 2020-09-30 21:17:25 +02:00
parent afc5475196
commit 301859b978
7 changed files with 77 additions and 98 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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++) {