Swipe in from the side edge to change pages on the Guition (0.2.29)

Page swipes were an LVGL gesture anywhere on the screen: 50 px, fast only,
and almost always starting on a tile that lit up as pressed. On the Guition
a touch that starts within 32 px of the left or right edge and travels
40 px inward, clearly sideways, now flips one page (from the right edge
leftwards is next, from the left edge rightwards previous), at any speed
and in every rotation; a swipe that starts in the middle does nothing, so
taps and drags on tiles can no longer change the page by accident. The
whole-screen gesture is removed from the Guition profile; the CYD keeps
it. Firmware 0.2.24 for both boards, the app only reworded the setting.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-14 11:40:19 +02:00
parent ea0b423fab
commit 104f20e4fa
13 changed files with 170 additions and 31 deletions
+44
View File
@@ -127,4 +127,48 @@ class TouchGuard {
Reject reject_{NONE};
};
inline TouchGuard touch_guard;
// Page navigation by swiping in from a side edge (Guition, firmware 0.2.24+). A touch that
// starts within `band` pixels of the left or right edge of the screen as the user sees it
// and travels `travel` pixels inward, clearly more sideways than up or down, flips one
// page: from the right edge leftwards is "next", from the left edge rightwards "previous".
// No speed requirement; a touch that starts in the middle never counts, so tapping and
// dragging on tiles cannot change the page by accident.
class EdgeSwipe {
public:
void configure(int width, int height, int band, int travel) {
width_ = width; height_ = height; band_ = band; travel_ = travel;
}
// Native touch coordinates plus the LVGL rotation in degrees (0, 90, 180, 270), mapped
// the way ESPHome's LVGL component rotates its pointer input.
void begin(int x, int y, int rotation = 0) {
rotation_ = rotation;
rotate(x, y);
start_x_ = x; start_y_ = y;
const int width = (rotation == 90 || rotation == 270) ? height_ : width_;
from_ = x < band_ ? 1 : x >= width - band_ ? -1 : 0; // 1: left edge, -1: right edge
done_ = false;
}
bool armed() const { return from_ != 0 && !done_; }
// +1 next page, -1 previous page, 0 nothing; fires at most once per touch.
int update(int x, int y) {
if (!armed()) return 0;
rotate(x, y);
const int dx = x - start_x_, dy = y - start_y_;
const int inward = from_ == 1 ? dx : -dx;
if (inward < travel_ || std::abs(dx) < 2 * std::abs(dy)) return 0;
done_ = true;
return from_ == 1 ? -1 : 1;
}
private:
void rotate(int &x, int &y) const {
if (rotation_ == 90) { const int tmp = y; y = width_ - x - 1; x = tmp; }
else if (rotation_ == 180) { x = width_ - x - 1; y = height_ - y - 1; }
else if (rotation_ == 270) { const int tmp = x; x = height_ - y - 1; y = tmp; }
}
int width_{480}, height_{480}, band_{32}, travel_{40}, rotation_{0};
int start_x_{0}, start_y_{0}, from_{0};
bool done_{true};
};
inline EdgeSwipe edge_swipe;
} // namespace cyd