From: adam Date: Thu, 16 Jun 2016 07:59:40 +0000 (+0300) Subject: Fixing ComboBox page flip on trackpad scroll (#19704) X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6a29505e5b9d68acdf37971be341e0d27d7ceda6;p=vaadin-framework.git Fixing ComboBox page flip on trackpad scroll (#19704) Trackpad scroll gesture produces a large amount of wheel events causing the same amount of flips on ComboBox. This fix tries to control page flips in a way that it would feel more natural to use it. Change-Id: I3ed206a5abe8c3ba8c06a5998f788468157663f1 --- diff --git a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java index 38f9642c16..3efd872e3b 100644 --- a/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/main/java/com/vaadin/client/ui/VFilterSelect.java @@ -244,7 +244,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, deltaY = -0.5*e.wheelDelta; } - @com.vaadin.client.ui.VFilterSelect.JsniUtil::moveScrollFromEvent(*)(widget, deltaX, deltaY, e); + @com.vaadin.client.ui.VFilterSelect.JsniUtil::moveScrollFromEvent(*)(widget, deltaX, deltaY, e, e.deltaMode); }); }-*/; @@ -258,12 +258,57 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * as much as feasible. */ static class JsniUtil { + private static final int DOM_DELTA_PIXEL = 0; + private static final int DOM_DELTA_LINE = 1; + private static final int DOM_DELTA_PAGE = 2; + + // Rough estimation of item height + private static final int SCROLL_UNIT_PX = 25; + + private static double deltaSum = 0; + public static void moveScrollFromEvent(final Widget widget, final double deltaX, final double deltaY, - final NativeEvent event) { + final NativeEvent event, final int deltaMode) { if (!Double.isNaN(deltaY)) { - ((VFilterSelect) widget).suggestionPopup.scroll(deltaY); + VFilterSelect filterSelect = (VFilterSelect) widget; + + switch (deltaMode) { + case DOM_DELTA_LINE: + if (deltaY >= 0) { + filterSelect.suggestionPopup.selectNextItem(); + } else { + filterSelect.suggestionPopup.selectPrevItem(); + } + break; + case DOM_DELTA_PAGE: + if (deltaY >= 0) { + filterSelect.selectNextPage(); + } else { + filterSelect.selectPrevPage(); + } + break; + case DOM_DELTA_PIXEL: + default: + // Accumulate dampened deltas + deltaSum += Math.pow(Math.abs(deltaY), 0.7) + * Math.signum(deltaY); + + // "Scroll" if change exceeds item height + while (Math.abs(deltaSum) >= SCROLL_UNIT_PX) { + if (!filterSelect.waitingForFilteringResponse) { + // Move selection if page flip is not in progress + if (deltaSum < 0) { + filterSelect.suggestionPopup.selectPrevItem(); + } else { + filterSelect.suggestionPopup.selectNextItem(); + } + } + deltaSum -= SCROLL_UNIT_PX * Math.signum(deltaSum); + } + break; + } } } } @@ -329,7 +374,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, @Override protected void onLoad() { super.onLoad(); - mouseWheeler.attachMousewheelListener(getElement()); + + // Register mousewheel listener on paged select + if (pageLength > 0) { + mouseWheeler.attachMousewheelListener(getElement()); + } } @Override