diff options
author | Ilia Motornyi <elmot@vaadin.com> | 2018-07-16 12:58:49 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-16 12:58:49 +0300 |
commit | 327544670c3688db309a14d117b939b47b50fcb3 (patch) | |
tree | b85926ee37c2999e9bda9bbbb0b4d599664d420f /compatibility-client/src/main/java/com | |
parent | 17761dc25992543e6bc45bf307c565cfef51d1d8 (diff) | |
download | vaadin-framework-327544670c3688db309a14d117b939b47b50fcb3.tar.gz vaadin-framework-327544670c3688db309a14d117b939b47b50fcb3.zip |
Ported change from 7.7 to compatibility - ComboBox popup position while scrolling (#11055)
Fixes #5043
Diffstat (limited to 'compatibility-client/src/main/java/com')
-rw-r--r-- | compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java index 920781a9c4..726efb5ec3 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java @@ -25,6 +25,8 @@ import java.util.Locale; import java.util.Set; import java.util.logging.Logger; +import com.google.gwt.animation.client.AnimationScheduler; +import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback; import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.Scheduler; @@ -56,6 +58,7 @@ import com.google.gwt.i18n.client.HasDirection.Direction; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Composite; @@ -355,8 +358,10 @@ public class VFilterSelect extends Composite private int popupOuterPadding = -1; private int topPosition; + private int leftPosition; private final MouseWheeler mouseWheeler = new MouseWheeler(); + private boolean scrollPending = false; /** * Default constructor @@ -444,12 +449,11 @@ public class VFilterSelect extends Composite getElement().setId("VAADIN_COMBOBOX_OPTIONLIST"); menu.setSuggestions(currentSuggestions); - final int x = VFilterSelect.this.getAbsoluteLeft(); + leftPosition = getDesiredLeftPosition(); - topPosition = tb.getAbsoluteTop(); - topPosition += tb.getOffsetHeight(); + topPosition = getDesiredTopPosition(); - setPopupPosition(x, topPosition); + setPopupPosition(leftPosition, topPosition); int nullOffset = (nullSelectionAllowed && "".equals(lastFilter) ? 1 : 0); @@ -496,6 +500,22 @@ public class VFilterSelect extends Composite }); } + private native int toInt32(double val) + /*-{ + return val | 0; + }-*/; + + private int getDesiredTopPosition() { + return toInt32(WidgetUtil.getBoundingClientRect(tb.getElement()) + .getBottom()) + Window.getScrollTop(); + } + + private int getDesiredLeftPosition() { + return toInt32(WidgetUtil + .getBoundingClientRect(VFilterSelect.this.getElement()) + .getLeft()); + } + /** * Should the next page button be visible to the user? * @@ -682,6 +702,47 @@ public class VFilterSelect extends Composite handleMouseDownEvent(event); } + @Override + protected void onPreviewNativeEvent(NativePreviewEvent event) { + // Check all events outside the combobox to see if they scroll the + // page. We cannot use e.g. Window.addScrollListener() because the + // scrolled element can be at any level on the page. + + // Normally this is only called when the popup is showing, but make + // sure we don't accidentally process all events when not showing. + if (!scrollPending && isShowing() && !DOM.isOrHasChild( + SuggestionPopup.this.getElement(), + Element.as(event.getNativeEvent().getEventTarget()))) { + if (getDesiredLeftPosition() != leftPosition + || getDesiredTopPosition() != topPosition) { + updatePopupPositionOnScroll(); + } + } + + super.onPreviewNativeEvent(event); + } + + /** + * Make the popup follow the position of the ComboBox when the page is + * scrolled. + */ + private void updatePopupPositionOnScroll() { + if (!scrollPending) { + AnimationScheduler.get() + .requestAnimationFrame(new AnimationCallback() { + public void execute(double timestamp) { + if (isShowing()) { + leftPosition = getDesiredLeftPosition(); + topPosition = getDesiredTopPosition(); + setPopupPosition(leftPosition, topPosition); + } + scrollPending = false; + } + }); + scrollPending = true; + } + } + /** * Should paging be enabled. If paging is enabled then only a certain * amount of items are visible at a time and a scrollbar or buttons are |