touchscreen: Kinetic scrolling v3
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 0e0982cb293ec6238cbd99f6ff2055b23c5decd1 Author: Aidan MacDonald <[email protected]> Date: Sun Nov 27 01:48:10 2022 +0000 touchscreen: Kinetic scrolling v3 Tune accel/decel/press coefficients and add a braking force which kicks in when swiping in the opposite direction of scrolling. This is instead of the usual acceleration force. Change-Id: I2b220c98674933a6957d6982020406342cd019bd diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c index 3d77afc929..ba155c0a16 100644 --- a/apps/gui/bitmap/list.c +++ b/apps/gui/bitmap/list.c @@ -561,22 +561,31 @@ struct kinetic { static struct kinetic kinetic; static struct gesture_vel list_gvel; +/* + * NOTE: defaults were chosen for the Shanling Q1, and may need + * tuning for other devices + */ + const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default = { - .a0 = 1000 << LIST_KINETIC_FRACBITS, - .a1 = 1 << (LIST_KINETIC_FRACBITS - 1), - /* delay is ignored for this one */ + .a0 = 200 << LIST_KINETIC_FRACBITS, /* 200.0 */ + .a1 = (6 << LIST_KINETIC_FRACBITS) / 5, /* 1.2 */ +}; + +const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default = { + .a0 = 200 << LIST_KINETIC_FRACBITS, /* 200.0 */ + .a1 = (1 << LIST_KINETIC_FRACBITS) / 2, /* 0.5 */ }; const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default = { - .a0 = 3000 << LIST_KINETIC_FRACBITS, - .a1 = 1 << (LIST_KINETIC_FRACBITS - 1), - .delay = 125 * HZ / 1000, + .a0 = 2000 << LIST_KINETIC_FRACBITS, /* 2000.0 */ + .a1 = (1 << LIST_KINETIC_FRACBITS) / 2, /* 0.5 */ + .delay = 125 * HZ / 1000, /* 125 ms */ }; const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default = { - .a0 = 35000 << LIST_KINETIC_FRACBITS, - .a1 = 4 << LIST_KINETIC_FRACBITS, - .delay = 250 * HZ / 1000, + .a0 = 35000 << LIST_KINETIC_FRACBITS, /* 35000.0 */ + .a1 = 4 << LIST_KINETIC_FRACBITS, /* 4.0 */ + .delay = 250 * HZ / 1000, /* 250 ms */ }; static void kinetic_stop_scrolling(struct kinetic *k, struct gui_synclist *list) @@ -683,22 +692,26 @@ static bool kinetic_start_scrolling(struct kinetic *k, struct gui_synclist *list return false; long yvel_fp = yvel << LIST_KINETIC_FRACBITS; + int vel_sgn = SIGN(k->cb_data.velocity); + if (list->scroll_mode == SCROLL_KINETIC) { - long accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX, - &global_settings.kinetic_scroll_accel); - accel = fp_mul(accel, RELOAD_INTERVAL_FP, LIST_KINETIC_FRACBITS); - - /* the acceleration is in the direction of the swipe */ - if (SIGN(accel) != SIGN(yvel_fp)) - accel = -accel; + long accel; + if (SIGN(yvel) == vel_sgn) + accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX, + &global_settings.kinetic_scroll_accel); + else + accel = -kinetic_calc_accel(k->cb_data.velocity, LONG_MAX, + &global_settings.kinetic_scroll_brake); yvel_fp += accel; } k->cb_data.list = list; k->cb_data.velocity += yvel_fp; - if (list->scroll_mode != SCROLL_KINETIC) + /* also reset distance & scroll duration after a direction change */ + if (list->scroll_mode != SCROLL_KINETIC || + vel_sgn != SIGN(k->cb_data.velocity)) { k->cb_data.distance = 0; k->cb_data.scroll_duration = 0; diff --git a/apps/gui/list.h b/apps/gui/list.h index 534558c0bc..0e3a350ed7 100644 --- a/apps/gui/list.h +++ b/apps/gui/list.h @@ -203,20 +203,25 @@ struct list_kinetic_scroll_settings long delay; }; -/* Acceleration applied to the scroll velocity when a swipe occurs during - * kinetic scrolling. This is needed to counteract the deceleration term - * for high scrolling speeds, since the user can only input a low constant - * acceleration from swiping alone. Delay is ignored. */ +/* + * accel: Extra impulse applied when swiping in the direction of scrolling, + * proportional to the current velocity. This is what allows for high + * scroll speeds. Delay is ignored. + * + * brake: Braking impulse applied when swiping in the opposite direction of + * scrolling, which helps to change direction quickly even at high + * speed. Delay is ignored. + * + * decel: Deceleration applied during scrolling. The delay is measured from + * the start of scrolling or last change of direction. + * + * press: Deceleration applied while the screen is pressed (motion is not + * needed to trigger). Additive with "decel". The delay is measured + * from the start of the press. + */ extern const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default; - -/* Deceleration applied to the scroll velocity during kinetic scrolling. - * The delay occurs right at the beginning of scrolling, eg. a delay of - * 1 second means deceleration starts 1 second after scrolling. */ +extern const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default; extern const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default; - -/* Deceleration applied during kinetic scrolling when the screen is - * pressed for longer than the delay interval (motion is not required). - * This is additive with list_kinetic_scroll_decel. */ extern const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default; #endif diff --git a/apps/settings.h b/apps/settings.h index 35af24c97d..f5d036f9da 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -801,6 +801,7 @@ struct user_settings int touch_mode; struct touchscreen_parameter ts_calibration_data; struct list_kinetic_scroll_settings kinetic_scroll_accel; + struct list_kinetic_scroll_settings kinetic_scroll_brake; struct list_kinetic_scroll_settings kinetic_scroll_decel; struct list_kinetic_scroll_settings kinetic_scroll_press; #endif diff --git a/apps/settings_list.c b/apps/settings_list.c index 958e61f07f..5d4e6e6cb7 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -2429,6 +2429,10 @@ const struct settings_list settings[] = { &list_kinetic_scroll_accel_default, "kinetic scroll accel", list_kinetic_load_from_cfg, list_kinetic_write_to_cfg, list_kinetic_is_default, list_kinetic_set_default), + CUSTOM_SETTING(0, kinetic_scroll_brake, -1, + &list_kinetic_scroll_brake_default, "kinetic scroll brake", + list_kinetic_load_from_cfg, list_kinetic_write_to_cfg, + list_kinetic_is_default, list_kinetic_set_default), CUSTOM_SETTING(0, kinetic_scroll_decel, -1, &list_kinetic_scroll_decel_default, "kinetic scroll decel", list_kinetic_load_from_cfg, list_kinetic_write_to_cfg, -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs