]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/tooltip/BaseTooltipParticipant.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / tooltip / BaseTooltipParticipant.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.tooltip;
13
14 import java.util.concurrent.Future;
15 import java.util.concurrent.TimeUnit;
16
17 import javax.swing.ToolTipManager;
18
19 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
20 import org.simantics.g2d.element.IElement;
21 import org.simantics.scenegraph.g2d.events.MouseEvent;
22 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
23 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
24 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
25 import org.simantics.scenegraph.g2d.events.command.Commands;
26 import org.simantics.utils.datastructures.hints.IHintContext.Key;
27 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
28 import org.simantics.utils.threads.ThreadUtils;
29
30 public abstract class BaseTooltipParticipant extends AbstractDiagramParticipant implements ITooltipParticipant {
31
32     // Element hint key for tooltips
33     public static Key TOOLTIP_KEY = new KeyOf(TooltipProvider.class, "TOOLTIP");
34
35     public int tooltipDelay = ToolTipManager.sharedInstance().getInitialDelay();
36
37     private IElement tooltipElement;
38     private TooltipProvider creator;
39     private boolean tooltipShowing = false;
40
41     private Future<?> delayRunnable = null;
42
43     private int x = 0;
44     private int y = 0;
45
46     @EventHandler(priority = 0)
47     public boolean handleKeyEvent(CommandEvent e) {
48         if (e.command == Commands.FOCUS_TOOLTIP) {
49             //System.out.println("Focus");
50             if (tooltipShowing && creator instanceof FocusableTooltipProvider) {
51                 ((FocusableTooltipProvider)creator).focus();
52             }
53         }
54         return false;
55     }
56
57     @EventHandler(priority = Integer.MAX_VALUE)
58     public boolean handleMouseEvent(MouseEvent e) {
59         if (e.screenPosition != null) {
60             x = (int)e.screenPosition.getX();
61             y = (int)e.screenPosition.getY();
62         }
63         if (tooltipShowing) {
64
65             if (e instanceof MouseButtonPressedEvent) {
66                 // this hides focused tooltip if mouse is clicked somewhere else that on the tooltip
67                 hideTooltip();
68             }
69         }
70         return  false;
71     }
72
73     /**
74      * Shows tooltip immediately
75      */
76     public synchronized void showTooltip() {
77         if (tooltipElement == null)
78             return;
79         creator.showTooltip(tooltipElement,x,y);
80         tooltipShowing = true;
81     }
82
83     private void launchThread() {
84         if (delayRunnable != null) {
85             delayRunnable.cancel(false);
86             delayRunnable = null;
87         }
88         delayRunnable = ThreadUtils.getNonBlockingWorkExecutor().schedule(new Runnable() {
89             @Override
90             public void run() {
91                 showTooltip();
92             }
93         }, tooltipDelay, TimeUnit.MILLISECONDS);
94     }
95
96     /**
97      * Tries to show tooltip for given element
98      * Does not show tooltip instantly, but uses delay
99      * @param element
100      */
101     public synchronized void showTooltipFor(IElement element) {
102         //System.out.println("showTooltipFor " + element);
103         if (tooltipShowing && (creator instanceof FocusableTooltipProvider) && ((FocusableTooltipProvider)creator).hasFocus())
104             return;
105         creator = element.getHint(TOOLTIP_KEY);
106         if (creator != null) {
107             tooltipElement = element;
108             launchThread();
109         } else {
110             hideTooltip();
111         }
112     }
113
114     /**
115      * Hides tooltip, if one is showing
116      */
117     public synchronized void hideTooltip() {
118         //System.out.println("hideTooltip");
119         if (tooltipShowing && (creator instanceof FocusableTooltipProvider) && ((FocusableTooltipProvider)creator).hasFocus())
120             return;
121         if (creator != null && tooltipShowing)
122             creator.hideTooltip(tooltipElement);
123         creator = null;
124         tooltipElement = null;
125         tooltipShowing = false;
126     }
127
128 }