blob: a5a25d142f4dc9569f453cc68b83f4541ba1ffba [file] [log] [blame]
/**
*
* 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;
}
}
}