/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.tooltip; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import javax.swing.ToolTipManager; import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; import org.simantics.g2d.element.IElement; import org.simantics.scenegraph.g2d.events.MouseEvent; import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; import org.simantics.scenegraph.g2d.events.command.CommandEvent; import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; import org.simantics.utils.threads.ThreadUtils; public abstract class BaseTooltipParticipant extends AbstractDiagramParticipant implements ITooltipParticipant { // Element hint key for tooltips public static Key TOOLTIP_KEY = new KeyOf(TooltipProvider.class, "TOOLTIP"); public int tooltipDelay = ToolTipManager.sharedInstance().getInitialDelay(); private IElement tooltipElement; private TooltipProvider creator; private boolean tooltipShowing = false; private Future delayRunnable = null; private int x = 0; private int y = 0; @EventHandler(priority = 0) public boolean handleKeyEvent(CommandEvent e) { if (e.command == Commands.FOCUS_TOOLTIP) { //System.out.println("Focus"); if (tooltipShowing && creator instanceof FocusableTooltipProvider) { ((FocusableTooltipProvider)creator).focus(); } } return false; } @EventHandler(priority = Integer.MAX_VALUE) public boolean handleMouseEvent(MouseEvent e) { if (e.screenPosition != null) { x = (int)e.screenPosition.getX(); y = (int)e.screenPosition.getY(); } if (tooltipShowing) { if (e instanceof MouseButtonPressedEvent) { // this hides focused tooltip if mouse is clicked somewhere else that on the tooltip hideTooltip(); } } return false; } /** * Shows tooltip immediately */ public synchronized void showTooltip() { if (tooltipElement == null) return; creator.showTooltip(tooltipElement,x,y); tooltipShowing = true; } private void launchThread() { if (delayRunnable != null) { delayRunnable.cancel(false); delayRunnable = null; } delayRunnable = ThreadUtils.getNonBlockingWorkExecutor().schedule(new Runnable() { @Override public void run() { showTooltip(); } }, tooltipDelay, TimeUnit.MILLISECONDS); } /** * Tries to show tooltip for given element * Does not show tooltip instantly, but uses delay * @param element */ public synchronized void showTooltipFor(IElement element) { //System.out.println("showTooltipFor " + element); if (tooltipShowing && (creator instanceof FocusableTooltipProvider) && ((FocusableTooltipProvider)creator).hasFocus()) return; creator = element.getHint(TOOLTIP_KEY); if (creator != null) { tooltipElement = element; launchThread(); } else { hideTooltip(); } } /** * Hides tooltip, if one is showing */ public synchronized void hideTooltip() { //System.out.println("hideTooltip"); if (tooltipShowing && (creator instanceof FocusableTooltipProvider) && ((FocusableTooltipProvider)creator).hasFocus()) return; if (creator != null && tooltipShowing) creator.hideTooltip(tooltipElement); creator = null; tooltipElement = null; tooltipShowing = false; } }