Take a slider let go within a centimetre of the glass edge as its end, because the panel loses a finger swiped off the screen before the slider's end (0.2.80)
A fast swipe off the right side of a Guition ended at 93-98 %: the GT911 reports the finger for the last time 33-48 px inside the edge while a wide tile's slider ends 29 px from it, and LVGL keeps the last point it saw. cyd::edge_snap() takes a release inside the band (SLIDER_EDGE_SNAP_PX: Guition 67, CYD 56) as the end that lies in that band, for the tile sliders and the light card's sliders; the log names each snap. App 0.2.80, firmware 0.2.67. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -219,4 +219,17 @@ inline bool release_jump(int held, int released, int minimum, int maximum) {
|
||||
const bool at_end = released <= minimum || released >= maximum;
|
||||
return at_end && std::abs(released - held) * 4 > maximum - minimum;
|
||||
}
|
||||
|
||||
// A slider whose end lies within `band` pixels of the screen's edge cannot be dragged to that end:
|
||||
// the panel loses a finger swiped off the glass before it gets there (a GT911 reports a fast swipe
|
||||
// for the last time 30-50 px inside the edge), and LVGL keeps the last point it saw. A finger let go
|
||||
// inside that band meant the end, as a pointer clamped to the bar does in Home Assistant's slider.
|
||||
// `point`, `start` and `end` lie along the slider's axis; returns -1 for the start, 1 for the end.
|
||||
inline int edge_snap(int point, int start, int end, int screen, int band) {
|
||||
if (band <= 0 || screen <= 0) return 0;
|
||||
if (end >= screen - band && point >= screen - band) return 1;
|
||||
if (start < band && point < band) return -1;
|
||||
return 0;
|
||||
}
|
||||
inline int edge_snap_band = 0;
|
||||
} // namespace cyd
|
||||
|
||||
@@ -117,6 +117,21 @@ inline void event(lv_event_t *e) {
|
||||
if (code == LV_EVENT_PRESS_LOST) row.dirty = false;
|
||||
if (code == LV_EVENT_RELEASED && row.dirty) {
|
||||
row.dirty = false;
|
||||
// A finger let go within the edge band of the glass meant the slider's end (cyd::edge_snap).
|
||||
if (auto *indev = lv_indev_active()) {
|
||||
lv_point_t p;
|
||||
lv_indev_get_point(indev, &p);
|
||||
lv_area_t a;
|
||||
lv_obj_get_coords(row.slider, &a);
|
||||
const int screen = lv_display_get_horizontal_resolution(lv_obj_get_display(row.slider));
|
||||
const int snap = cyd::edge_snap(p.x, a.x1, a.x2, screen, cyd::edge_snap_band);
|
||||
if (snap) {
|
||||
const int end = snap > 0 ? lv_slider_get_max_value(row.slider) : lv_slider_get_min_value(row.slider);
|
||||
ESP_LOGI("slider", "Let go %d px from the %s edge: slider %d -> %d", snap > 0 ? screen - 1 - (int) p.x : (int) p.x, snap > 0 ? "right" : "left", lv_slider_get_value(row.slider), end);
|
||||
lv_slider_set_value(row.slider, end, LV_ANIM_OFF);
|
||||
preview(row);
|
||||
}
|
||||
}
|
||||
int value = lv_slider_get_value(row.slider);
|
||||
if (row.index == 0) active->hue = value;
|
||||
if (row.index == 1) {
|
||||
|
||||
@@ -895,6 +895,15 @@ inline void slider_event(lv_event_t *e){
|
||||
// A slider among a card's own parts (the media tile's volume) belongs to the tile the slot shows now.
|
||||
for(auto &w:widgets)if(w.slider==slider || w.control_slider==slider || (w.extra && lv_obj_get_parent(slider)==w.extra)){index=w.index;break;}
|
||||
bool changed=slider_changed;captured_slider=nullptr;slider_changed=false;
|
||||
// A finger let go within the edge band of the glass meant the slider's end (cyd::edge_snap).
|
||||
if(auto *indev=lv_indev_active();indev && lv_obj_get_width(slider)>=lv_obj_get_height(slider)){
|
||||
lv_point_t p;lv_indev_get_point(indev,&p);lv_area_t a;lv_obj_get_coords(slider,&a);
|
||||
int screen=lv_display_get_horizontal_resolution(lv_obj_get_display(slider));
|
||||
int snap=cyd::edge_snap(p.x,a.x1,a.x2,screen,cyd::edge_snap_band);
|
||||
if(snap){int end=snap>0?(int)lv_slider_get_max_value(slider):std::max(0,(int)lv_slider_get_min_value(slider));
|
||||
ESP_LOGI("slider","Let go %d px from the %s edge: slider %d -> %d",snap>0?screen-1-(int)p.x:(int)p.x,snap>0?"right":"left",lv_slider_get_value(slider),end);
|
||||
lv_slider_set_value(slider,end,LV_ANIM_OFF);changed=true;}
|
||||
}
|
||||
if(changed && cyd::touch_guard.accept_slider(esphome::millis(),200+index))commit_slider(index,lv_slider_get_value(slider));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user