| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Florian Pirchner <florian.pirchner@gmail.com> - Initial implementation |
| */ |
| package org.eclipse.osbp.vaadin.addons.designer.overlay.client.widgets; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Stack; |
| |
| import org.eclipse.osbp.vaadin.addons.designer.overlay.client.OAbstractOverlay; |
| |
| import com.google.gwt.dom.client.Element; |
| import com.google.gwt.user.client.ui.Widget; |
| |
| /** |
| * Controls, that only one overlay is opened at a time. The delay for closing |
| * the overlay is too long to avoid multiple overlays. |
| */ |
| public class OOverlayController { |
| |
| /** The Constant instance. */ |
| private static final OOverlayController instance = new OOverlayController(); |
| |
| /** |
| * Gets the single instance of OOverlayController. |
| * |
| * @return single instance of OOverlayController |
| */ |
| public static OOverlayController getInstance() { |
| return instance; |
| } |
| |
| /** The show timer. */ |
| // private Timer showTimer; |
| |
| /** The current opened. */ |
| private OAbstractOverlay currentOpened; |
| |
| private Map<Element, OAbstractOverlay> map = new HashMap<>(); |
| private Stack<Element> navigationStack = new Stack<>(); |
| |
| /** |
| * Instantiates a new o overlay controller. |
| */ |
| private OOverlayController() { |
| |
| } |
| |
| /** |
| * Registers the element with the overlay. This is required to use arrow UP |
| * to navigate to the next higher overlay in the element hierarchy. |
| * |
| * @param element |
| * @param overlay |
| */ |
| public void register(Element element, OAbstractOverlay overlay) { |
| map.put(element, overlay); |
| } |
| |
| /** |
| * Unregisters the element with its overlay. |
| * |
| * @param element |
| */ |
| public void unregister(Element element) { |
| map.remove(element); |
| } |
| |
| /** |
| * Uses the current opened overlay and navigates up the element hierarchy |
| * until an element associated with an overlay could be found. This overlay |
| * will be shown. |
| */ |
| public void navigateUp() { |
| if (currentOpened == null) { |
| navigationStack.clear(); |
| return; |
| } |
| |
| Element element = currentOpened.getOwner().getElement(); |
| OAbstractOverlay nextHigher = findOverlayInParent(element); |
| if (nextHigher != null) { |
| navigationStack.push(element); |
| Widget widget = nextHigher.getOwner(); |
| show(nextHigher, widget.getElement().getAbsoluteLeft(), widget.getElement().getAbsoluteTop(), false); |
| } |
| } |
| |
| /** |
| * Uses the current opened overlay and navigates down the last opened |
| * overlays. |
| */ |
| public void navigateDown() { |
| if (currentOpened == null || navigationStack.isEmpty()) { |
| navigationStack.clear(); |
| return; |
| } |
| |
| Element lastElement = navigationStack.pop(); |
| if (lastElement != null) { |
| show(map.get(lastElement), lastElement.getAbsoluteLeft(), lastElement.getAbsoluteTop(), false); |
| } |
| } |
| |
| private OAbstractOverlay findOverlayInParent(Element element) { |
| Element parent = element.getParentElement(); |
| if (parent == null) { |
| return null; |
| } |
| if (map.containsKey(parent)) { |
| return map.get(parent); |
| } |
| |
| return findOverlayInParent(parent); |
| } |
| |
| /** |
| * Notifies the controller, that a new overlay is about to show. The |
| * controller will ensure, that a currently opened overlay will be closed |
| * Immediately. |
| * |
| * @param overlay |
| * the overlay |
| * @param left |
| * the left |
| * @param top |
| * the top |
| */ |
| public void show(OAbstractOverlay overlay, int left, int top) { |
| show(overlay, left, top, true); |
| } |
| |
| private void show(OAbstractOverlay overlay, int left, int top, boolean clearStack) { |
| if (clearStack) { |
| navigationStack.clear(); |
| } |
| |
| if (currentOpened == overlay && currentOpened.isShowing()) { |
| return; |
| } |
| |
| if (currentOpened != null) { |
| currentOpened.hide(); |
| } |
| |
| overlay.setPopupPosition(left, top); |
| currentOpened = overlay; |
| |
| if (currentOpened != null) { |
| currentOpened.show(); |
| } |
| } |
| |
| /** |
| * Closes the currently opened overlay. |
| */ |
| public void close() { |
| navigationStack.clear(); |
| if (currentOpened != null) { |
| currentOpened.hide(); |
| currentOpened = null; |
| } |
| } |
| |
| } |