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