/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.wui.client.common.popup; import org.roda.core.data.v2.common.Pair; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.UIObject; public class CalloutPopup extends PopupPanel { private static final int MARGIN_FROM_TARGET_PX = 10; private static final int ARROW_OFFSET_PX = 16; public enum CalloutPosition { BOTTOM_RIGHT, TOP_RIGHT; } public CalloutPopup() { super(true, true); init(); } public CalloutPopup(boolean autoHide, boolean modal) { super(autoHide, modal); init(); } public CalloutPopup(boolean autoHide) { super(autoHide); init(); } private void init() { setStyleName("actions-popup"); } public void showRelativeTo(final UIObject target, final CalloutPosition position) { addStyleDependentName(position.name().toLowerCase()); setPopupPositionAndShow(new PositionCallback() { @Override public void setPosition(int offsetWidth, int offsetHeight) { showRelativeTo(target, position, offsetWidth, offsetHeight); } }); } private void showRelativeTo(UIObject target, CalloutPosition position, int offsetWidth, int offsetHeight) { Pair<Integer, Integer> positionPair = Pair.of(0, 0); if (CalloutPosition.BOTTOM_RIGHT.equals(position)) { positionPair = getBottomRight(target, offsetWidth, offsetHeight); } else if (CalloutPosition.TOP_RIGHT.equals(position)) { positionPair = getTopRight(target, offsetWidth, offsetHeight); } setPopupPosition(positionPair.getFirst(), positionPair.getSecond()); } private Pair<Integer, Integer> getBottomRight(UIObject target, int offsetWidth, int offsetHeight) { int left = target.getAbsoluteLeft() + target.getOffsetWidth() / 2 - offsetWidth + ARROW_OFFSET_PX; int top = target.getAbsoluteTop() - offsetHeight - MARGIN_FROM_TARGET_PX; // change top value if popup top disappears of the page (goes to bottom) if (top < 0) { top = target.getAbsoluteTop() + target.getOffsetHeight() + MARGIN_FROM_TARGET_PX; addStyleDependentName(CalloutPosition.TOP_RIGHT.name().toLowerCase()); } else { addStyleDependentName(CalloutPosition.BOTTOM_RIGHT.name().toLowerCase()); } return Pair.of(left, top); } private Pair<Integer, Integer> getTopRight(UIObject target, int offsetWidth, int offsetHeight) { int left = target.getAbsoluteLeft() + target.getOffsetWidth() / 2 - offsetWidth + ARROW_OFFSET_PX; int top = target.getAbsoluteTop() + target.getOffsetHeight() + MARGIN_FROM_TARGET_PX; addStyleDependentName(CalloutPosition.TOP_RIGHT.name().toLowerCase()); return Pair.of(left, top); } }