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:
parent
afc5475196
commit
301859b978
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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++) {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user