package pl.djvuhtml5.client.ui; import java.util.ArrayList; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Widget; public class UIHider implements MouseMoveHandler, MouseOverHandler, MouseOutHandler, KeyDownHandler, TouchStartHandler, ScrollHandler { private static class UIElement { public final Widget widget; public final String hiddenStyleName; public UIElement(Widget widget, String hiddenStyleName) { this.widget = widget; this.hiddenStyleName = hiddenStyleName; } } private final int uiHideDelay; private final ArrayList<UIElement> uiElements = new ArrayList<>(); private int previousX, previousY; private boolean isMouseOverUI = false; private final Timer timer = new Timer() { @Override public void run() { hideUI(); } }; public UIHider(int uiHideDelay, Widget textLayer) { this.uiHideDelay = uiHideDelay; textLayer.addDomHandler(this, MouseMoveEvent.getType()); textLayer.addDomHandler(this, KeyDownEvent.getType()); textLayer.addDomHandler(this, ScrollEvent.getType()); textLayer.addDomHandler(this, TouchStartEvent.getType()); } public void addUIElement(Widget widget, String hiddenStyleName) { uiElements.add(new UIElement(widget, hiddenStyleName)); widget.addDomHandler(this, MouseOverEvent.getType()); widget.addDomHandler(this, MouseOutEvent.getType()); } private void showUI() { for (UIElement element : uiElements) element.widget.removeStyleName(element.hiddenStyleName); timer.cancel(); timer.schedule(uiHideDelay); } private void hideUI() { if (isMouseOverUI || isUIFocused()) return; for (UIElement element : uiElements) element.widget.addStyleName(element.hiddenStyleName); } private boolean isUIFocused() { Element focusedElement = getFocusedElement(); while (focusedElement != null) { for (UIElement element : uiElements) { if (element.widget.getElement() == focusedElement) return true; } focusedElement = focusedElement.getParentElement(); } return false; } private native final static Element getFocusedElement() /*-{ return $doc.activeElement; }-*/; @Override public void onMouseMove(MouseMoveEvent event) { if (previousX == event.getX() && previousY == event.getY()) return; previousX = event.getX(); previousY = event.getY(); showUI(); } @Override public void onTouchStart(TouchStartEvent event) { isMouseOverUI = false; showUI(); } @Override public void onMouseOver(MouseOverEvent event) { isMouseOverUI = true; } @Override public void onMouseOut(MouseOutEvent event) { isMouseOverUI = false; } @Override public void onKeyDown(KeyDownEvent event) { showUI(); } @Override public void onScroll(ScrollEvent event) { showUI(); } }