🎨 Touch code formatting

This commit is contained in:
Scott Lahteine
2026-03-13 17:26:33 -05:00
parent 7a226ad73b
commit c73245a3d9
2 changed files with 99 additions and 82 deletions

View File

@@ -82,87 +82,92 @@ void Touch::idle() {
if (now == next_touch_ms) return;
next_touch_ms = now;
// Get the point and if the screen is touched do more
// Get the point where the screen is touched
int16_t _x, _y;
if (get_point(&_x, &_y)) {
const bool is_touched = get_point(&_x, &_y);
#if HAS_RESUME_CONTINUE
// UI is waiting for a click anywhere?
if (marlin.wait_for_user) {
touch_control_type = CLICK;
ui.lcd_clicked = true;
if (ui.external_control) marlin.user_resume();
return;
}
#endif
ui.reset_status_timeout(now);
// If nada_start_ms is set the touch is being held down outside of a control.
// With TOUCH_SCREEN_CALIBRATION a long hold (2.5s by default) opens to the calibration screen.
// As long as this non-action touch is still held down, return.
if (nada_start_ms) {
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
if (touch_control_type == NONE && ELAPSED(now, nada_start_ms, TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS) && ui.on_status_screen())
ui.goto_screen(touch_screen_calibration);
#endif
return;
}
// First time touched, ignore the control for a tiny interval as a debounce
if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME;
// For a held control ignore the continuing touch until time elapses
// to prevent spamming controls.
if (PENDING(now, time_to_hold)) return;
// Was a previous point recorded? Then we are dragging, maybe in a control.
if (x != 0 && y != 0) {
// If a control was set by hold() keep sliding it until its bounds are exited
if (current_control) {
if (WITHIN(x, current_control->x - FREE_MOVE_RANGE, current_control->x + current_control->width + FREE_MOVE_RANGE) && WITHIN(y, current_control->y - FREE_MOVE_RANGE, current_control->y + current_control->height + FREE_MOVE_RANGE)) {
LIMIT(x, current_control->x, current_control->x + current_control->width);
LIMIT(y, current_control->y, current_control->y + current_control->height);
touch(current_control);
}
else
current_control = nullptr;
}
else {
// Initiate a touch on the first control containing the touch position
// If this is a button the touch initiates the action on the button.
// TODO: Apply standard UI practice for Tap events:
// - Take a short press-and-release as a Tap.
// - If more taps occur before "tap detect time" elapses, increment taps counter.
// - When "tap detect time" elapses activate the button, sending the number of taps.
for (uint16_t i = 0; i < controls_count; ++i) {
auto &c = controls[i];
if ((WITHIN(x, c.x, c.x + c.width) && WITHIN(y, c.y, c.y + c.height)) || TERN0(TOUCH_SCREEN_CALIBRATION, c.type == CALIBRATE)) {
touch_control_type = c.type;
touch(&c);
break;
}
}
}
if (!current_control)
nada_start_ms = now;
}
x = _x;
y = _y;
}
else {
// No touch is occurring. Continually reset these values:
// If no touch is occurring then reset all touch info and exit
if (!is_touched) {
x = y = 0;
current_control = nullptr;
nada_start_ms = 0;
touch_control_type = NONE;
time_to_hold = 0;
repeat_delay = TOUCH_REPEAT_DELAY;
repeat_delay = MINIMUM_HOLD_TIME;
return;
}
// A new touch or a drag...
#if HAS_RESUME_CONTINUE
// UI is waiting for a click anywhere?
if (marlin.wait_for_user) {
touch_control_type = CLICK;
ui.lcd_clicked = true;
if (ui.external_control) marlin.user_resume();
return;
}
#endif
ui.reset_status_timeout(now);
// If nada_start_ms is set, a touch outside of controls is being held down.
// With TOUCH_SCREEN_CALIBRATION a long hold (2.5s by default) opens to the calibration screen.
// As long as this non-action touch is still held down, return.
if (nada_start_ms) {
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
if (touch_control_type == NONE && ELAPSED(now, nada_start_ms, TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS) && ui.on_status_screen())
ui.goto_screen(touch_screen_calibration);
#endif
return;
}
// First time touched, ignore the control for a tiny interval as a debounce
if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME;
// For a held control ignore the continuing touch until time elapses
// to prevent spamming controls.
// This timestamp will be updated as controls are held down.
if (PENDING(now, time_to_hold)) return;
// Was a previous point recorded? Then we are dragging, maybe in a control.
if (x != 0 && y != 0) {
// If a control was set by hold() keep sliding it until its bounds are exited
if (current_control) {
if (WITHIN(x, current_control->x - FREE_MOVE_RANGE, current_control->x + current_control->width + FREE_MOVE_RANGE) && WITHIN(y, current_control->y - FREE_MOVE_RANGE, current_control->y + current_control->height + FREE_MOVE_RANGE)) {
LIMIT(x, current_control->x, current_control->x + current_control->width);
LIMIT(y, current_control->y, current_control->y + current_control->height);
touch(current_control);
}
else
current_control = nullptr;
}
else {
// Initiate a touch on the first control containing the touch position.
// If this is a button the touch initiates the action on the button.
// TODO: Apply standard UI practice for Tap events:
// - Take a short press-and-release as a Tap.
// - If more taps occur before "tap detect time" elapses, increment taps counter.
// - When "tap detect time" elapses activate the button, sending the number of taps.
for (uint16_t i = 0; i < controls_count; ++i) {
auto &c = controls[i];
if ((WITHIN(x, c.x, c.x + c.width) && WITHIN(y, c.y, c.y + c.height)) || TERN0(TOUCH_SCREEN_CALIBRATION, c.type == CALIBRATE)) {
touch_control_type = c.type;
touch(&c);
break;
}
}
}
if (!current_control) nada_start_ms = now;
}
// Update previous point in continuing touch or drag
x = _x;
y = _y;
}
// Handle a touch first detected in a control
// Handle a touch, repeat-touch, or drag in a control
void Touch::touch(touch_control_t * const control) {
switch (control->type) {
@@ -217,11 +222,20 @@ void Touch::touch(touch_control_t * const control) {
break;
// A slider is held until the touch ends, no repeat delay
case SLIDER: hold(control); ui.encoderPosition = (x - control->x) * control->data / control->width; break;
case SLIDER:
hold(control);
ui.encoderPosition = (x - control->x) * control->data / control->width;
break;
// Increase / Decrease controls are held with a repeat delay
case INCREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff++ : ui.encoderPosition++, ui.encoderPosition++); break;
case DECREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff-- : ui.encoderPosition--, ui.encoderPosition--); break;
// Increase / Decrease controls are held with an ever-decreasing repeat delay
case INCREASE:
hold(control, repeat_delay - 5, TOUCH_REPEAT_FIRST_DELAY);
TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff++ : ui.encoderPosition++, ui.encoderPosition++);
break;
case DECREASE:
hold(control, repeat_delay - 5, TOUCH_REPEAT_FIRST_DELAY);
TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff-- : ui.encoderPosition--, ui.encoderPosition--);
break;
// Other controls behave like menu items
@@ -296,7 +310,10 @@ void Touch::touch(touch_control_t * const control) {
break;
#if ENABLED(AUTO_BED_LEVELING_UBL)
case UBL: hold(control, UBL_REPEAT_DELAY); ui.encoderPosition += control->data; break;
case UBL:
hold(control, UBL_REPEAT_DELAY, TOUCH_REPEAT_FIRST_DELAY);
ui.encoderPosition += control->data;
break;
#endif
// TODO: TOUCH could receive data to pass to the callback

View File

@@ -64,12 +64,12 @@ typedef struct __attribute__((__packed__)) {
intptr_t data;
} touch_control_t;
#define MAX_CONTROLS 16
#define MINIMUM_HOLD_TIME 15
#define TOUCH_REPEAT_DELAY 75
#define MIN_REPEAT_DELAY 25
#define UBL_REPEAT_DELAY 125
#define FREE_MOVE_RANGE 32
#define MAX_CONTROLS 16
#define MINIMUM_HOLD_TIME 15 // Debounce delay for ignoring short accidental touch
#define TOUCH_REPEAT_DELAY 100 // 1/10s Repeat delay for key-like buttons
#define MIN_REPEAT_DELAY 25 // Smallest permitted repeat delay for controls that speed up the longer they are held
#define UBL_REPEAT_DELAY 125 // Repeat delay for a held control
#define FREE_MOVE_RANGE 32 // Area around a control allowed before aborting a held control
#define TSLP_SLEEPING 1