Browse Source

Ported change from 7.7 to compatibility - ComboBox popup position while scrolling (#11055)

Fixes #5043
tags/8.6.0.alpha1
Ilia Motornyi 5 years ago
parent
commit
327544670c
No account linked to committer's email address

+ 65
- 4
compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java View File

@@ -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

Loading…
Cancel
Save