package com.project.shared.client.utils.widgets; import com.google.common.base.Strings; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.ContextMenuEvent; import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.HumanInputEvent; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.TouchEndEvent; import com.google.gwt.event.dom.client.TouchEndHandler; import com.google.gwt.event.dom.client.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchMoveHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.event.logical.shared.AttachEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.HasEnabled; import com.google.gwt.user.client.ui.Widget; import com.project.shared.client.events.SimpleEvent; import com.project.shared.client.events.SimpleEvent.Handler; import com.project.shared.client.handlers.RegistrationsManager; import com.project.shared.client.utils.ElementUtils; import com.project.shared.client.utils.HandlerUtils; import com.project.shared.data.Point2D; import com.project.shared.data.funcs.AsyncFunc; import com.project.shared.data.funcs.Func; public class WidgetUtils { public static void stopClickPropagation(Widget widget) { widget.addDomHandler(new ClickHandler() { public void onClick(ClickEvent arg0) { arg0.stopPropagation(); } }, ClickEvent.getType()); WidgetUtils.addMovementStartHandler(widget, new Handler<HumanInputEvent<?>>() { @Override public void onFire(HumanInputEvent<?> arg) { arg.stopPropagation(); }}); } public static <T extends Widget & Focusable> void addEscapeUnfocusesHandler(final T widget) { widget.addDomHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.getNativeKeyCode() == 27) { widget.setFocus(false); } } }, KeyDownEvent.getType()); } public static HandlerRegistration stopMouseMovePropagation(Widget widget) { return widget.addDomHandler(new MouseMoveHandler() { @Override public void onMouseMove(MouseMoveEvent event) { event.stopPropagation(); } }, MouseMoveEvent.getType()); } public static void mouseDownPreventDefault(Widget widget) { WidgetUtils.addMovementStartHandler(widget, new Handler<HumanInputEvent<?>>() { @Override public void onFire(HumanInputEvent<?> arg) { arg.preventDefault(); }}); } public static void setWidgetSize(Widget widget, Point2D editSize) { widget.setWidth(editSize.getX() + "px"); widget.setHeight(editSize.getY() + "px"); } public static void setBackgroundImageAsync(final Widget widget, String imageUrl, String errorImageUrl, final boolean autoSize, final String loadingStyleName) { WidgetUtils.setBackgroundImageAsync(widget, imageUrl, errorImageUrl, autoSize, loadingStyleName, HandlerUtils.<Void>emptyHandler(), HandlerUtils.<Void>emptyHandler()); } public static void setBackgroundImageAsync(final Widget widget, String imageUrl, String errorImageUrl, final boolean autoSize, final SimpleEvent.Handler<Void> loadHandler, final SimpleEvent.Handler<Void> errorHandler) { WidgetUtils.setBackgroundImageAsync(widget, imageUrl, errorImageUrl, autoSize, "", loadHandler, HandlerUtils.<Void>emptyHandler()); } public static void setBackgroundImageAsync(final Widget widget, String imageUrl, String errorImageUrl, final boolean autoSize, final String loadingStyleName, final SimpleEvent.Handler<Void> loadHandler, final SimpleEvent.Handler<Void> errorHandler) { widget.getElement().getStyle().clearBackgroundImage(); if (Strings.isNullOrEmpty(imageUrl)) { WidgetUtils.removeNonEmptyStyleName(widget, loadingStyleName); loadHandler.onFire(null); return; } WidgetUtils.addNonEmptyStyleName(widget, loadingStyleName); ElementUtils.setBackgroundImageAsync(widget.getElement(), imageUrl, errorImageUrl, autoSize, new SimpleEvent.Handler<Void>() { @Override public void onFire(Void arg) { WidgetUtils.removeNonEmptyStyleName(widget, loadingStyleName); loadHandler.onFire(null); }}, new SimpleEvent.Handler<Void>() { @Override public void onFire(Void arg) { WidgetUtils.removeNonEmptyStyleName(widget, loadingStyleName); errorHandler.onFire(null); }}); } /** * Returns an AsyncFunc that waits until the widget is attached to the DOM, and the completes (runs once). * If the widget is already attached, it will complete immediately. * @param widget * @return */ public static AsyncFunc<Void, Void> getOnAttachAsyncFunc(final Widget widget) { if (widget.isAttached()) { return AsyncFunc.immediate(); } return new AsyncFunc<Void,Void>(){ @Override protected <S, E> void run(Void arg, final Func<Void, S> successHandler, Func<Throwable, E> errorHandler) { if (widget.isAttached()) { successHandler.apply(null); return; } final RegistrationsManager regs = new RegistrationsManager(); regs.add(widget.addAttachHandler(new AttachEvent.Handler() { @Override public void onAttachOrDetach(AttachEvent event) { if (false == event.isAttached()) { return; } regs.clear(); successHandler.apply(null); } })); } }; } public static void disableContextMenu(Widget widget){ widget.addDomHandler(new ContextMenuHandler() { @Override public void onContextMenu(ContextMenuEvent event) { event.preventDefault(); } }, ContextMenuEvent.getType()); } public static Func.VoidAction setEnabledFunc(final HasEnabled widget, final boolean isEnabled) { return new Func.VoidAction() { @Override public void exec() { widget.setEnabled(isEnabled); } }; } public static void addNonEmptyStyleName(Widget widget, String style) { if (Strings.isNullOrEmpty(style)) { return; } widget.addStyleName(style); } public static void removeNonEmptyStyleName(Widget widget, String style) { if (Strings.isNullOrEmpty(style)) { return; } widget.removeStyleName(style); } public static HandlerRegistration addMovementStartHandler(Widget widget, final SimpleEvent.Handler<HumanInputEvent<?>> handler) { RegistrationsManager regs = new RegistrationsManager(); regs.add(widget.addDomHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { handler.onFire(event); } }, MouseDownEvent.getType())); regs.add(widget.addDomHandler(new TouchStartHandler() { @Override public void onTouchStart(TouchStartEvent event) { handler.onFire(event); } }, TouchStartEvent.getType())); return regs.asSingleRegistration(); } private static class Container<T> { public T value; public Container() {} } public static HandlerRegistration addMovementStopHandler(Widget widget, final SimpleEvent.Handler<HumanInputEvent<?>> handler) { RegistrationsManager regs = new RegistrationsManager(); regs.add(widget.addDomHandler(new MouseUpHandler() { @Override public void onMouseUp(MouseUpEvent event) { handler.onFire(event); } }, MouseUpEvent.getType())); // This mess is here because touch end events don't contain the touch information of the last position in the movement. final Container<TouchMoveEvent> lastTouchMoveEventContainer = new Container<TouchMoveEvent>(); regs.add(widget.addDomHandler(new TouchMoveHandler() { @Override public void onTouchMove(TouchMoveEvent event) { lastTouchMoveEventContainer.value = event; } }, TouchMoveEvent.getType())); regs.add(widget.addDomHandler(new TouchEndHandler() { @Override public void onTouchEnd(final TouchEndEvent event) { handler.onFire(lastTouchMoveEventContainer.value); } }, TouchEndEvent.getType())); return regs.asSingleRegistration(); } public static HandlerRegistration addMovementMoveHandler(Widget widget, final SimpleEvent.Handler<HumanInputEvent<?>> handler) { RegistrationsManager regs = new RegistrationsManager(); regs.add(widget.addDomHandler(new MouseMoveHandler() { @Override public void onMouseMove(MouseMoveEvent event) { handler.onFire(event); } }, MouseMoveEvent.getType())); regs.add(widget.addDomHandler(new TouchMoveHandler() { @Override public void onTouchMove(TouchMoveEvent event) { handler.onFire(event); } }, TouchMoveEvent.getType())); return regs.asSingleRegistration(); } }