| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.draw2d; |
| |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.MouseTrackAdapter; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Display; |
| |
| import org.eclipse.draw2d.geometry.Dimension; |
| |
| /** |
| * This class is used by SWTEventDispatcher as support to display Figure |
| * tooltips on a mouse hover event. Tooltips are drawn directly below the cursor |
| * unless the display does not allow, in which case the tooltip will be drawn |
| * directly above the cursor. Tooltips will be displayed with a LineBorder. The |
| * background of the tooltips will be the standard SWT tooltipBackground color |
| * unless the Figure's tooltip has set its own background. |
| */ |
| public class ToolTipHelper extends PopUpHelper { |
| |
| private Timer timer; |
| private IFigure currentTipSource; |
| private int hideDelay = 5000; |
| |
| /** |
| * Constructs a ToolTipHelper to be associated with Control <i>c</i>. |
| * |
| * @param c |
| * the control |
| * @since 2.0 |
| */ |
| public ToolTipHelper(org.eclipse.swt.widgets.Control c) { |
| super(c, SWT.TOOL | SWT.ON_TOP); |
| getShell().setBackground(ColorConstants.tooltipBackground()); |
| getShell().setForeground(ColorConstants.tooltipForeground()); |
| } |
| |
| /* |
| * Calculates the location where the tooltip will be painted. Returns this |
| * as a Point. Tooltip will be painted directly below the cursor if |
| * possible, otherwise it will be painted directly above cursor. |
| */ |
| private Point computeWindowLocation(IFigure tip, int eventX, int eventY) { |
| org.eclipse.swt.graphics.Rectangle clientArea = control.getDisplay() |
| .getClientArea(); |
| Point preferredLocation = new Point(eventX, eventY + 26); |
| |
| Dimension tipSize = getLightweightSystem().getRootFigure() |
| .getPreferredSize().getExpanded(getShellTrimSize()); |
| |
| // Adjust location if tip is going to fall outside display |
| if (preferredLocation.y + tipSize.height > clientArea.height) |
| preferredLocation.y = eventY - tipSize.height; |
| |
| if (preferredLocation.x + tipSize.width > clientArea.width) |
| preferredLocation.x -= (preferredLocation.x + tipSize.width) |
| - clientArea.width; |
| |
| return preferredLocation; |
| } |
| |
| /** |
| * Sets the tooltip hide delay, which is the amount in ms, after which the |
| * tooltip will disappear again. |
| * |
| * @param hideDelay |
| * The delay after which the tooltip is hidden again, in ms. |
| * @since 3.10 |
| */ |
| public void setHideDelay(int hideDelay) { |
| this.hideDelay = hideDelay; |
| } |
| |
| /** |
| * Sets the LightWeightSystem's contents to the passed tooltip, and displays |
| * the tip. The tip will be displayed only if the tip source is different |
| * than the previously viewed tip source. (i.e. The cursor has moved off of |
| * the previous tooltip source figure.) |
| * <p> |
| * The tooltip will be painted directly below the cursor if possible, |
| * otherwise it will be painted directly above cursor. |
| * |
| * @param hoverSource |
| * the figure over which the hover event was fired |
| * @param tip |
| * the tooltip to be displayed |
| * @param eventX |
| * the x coordinate of the hover event |
| * @param eventY |
| * the y coordinate of the hover event |
| * @since 2.0 |
| */ |
| public void displayToolTipNear(IFigure hoverSource, IFigure tip, |
| int eventX, int eventY) { |
| if (tip != null && hoverSource != currentTipSource) { |
| getLightweightSystem().setContents(tip); |
| Point displayPoint = computeWindowLocation(tip, eventX, eventY); |
| Dimension shellSize = getLightweightSystem().getRootFigure() |
| .getPreferredSize().getExpanded(getShellTrimSize()); |
| setShellBounds(displayPoint.x, displayPoint.y, shellSize.width, |
| shellSize.height); |
| show(); |
| currentTipSource = hoverSource; |
| timer = new Timer(true); |
| timer.schedule(new TimerTask() { |
| public void run() { |
| //[ariddle] - changed for RAP compatibility |
| control.getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| hide(); |
| } |
| }); |
| } |
| }, hideDelay); |
| } |
| } |
| |
| /** |
| * Disposes of the tooltip's shell and kills the timer. |
| * |
| * @see PopUpHelper#dispose() |
| */ |
| public void dispose() { |
| if (isShowing()) { |
| hide(); |
| } |
| getShell().dispose(); |
| } |
| |
| protected void hide() { |
| if (timer != null) { |
| timer.cancel(); |
| } |
| super.hide(); |
| } |
| |
| /** |
| * @see PopUpHelper#hookShellListeners() |
| */ |
| protected void hookShellListeners() { |
| // Close the tooltip window if the mouse enters the tooltip |
| // UNSUPPORTED - api not implemented in RAP |
| // getShell().addMouseTrackListener(new MouseTrackAdapter() { |
| // public void mouseEnter(org.eclipse.swt.events.MouseEvent e) { |
| // hide(); |
| // currentTipSource = null; |
| // } |
| // }); |
| } |
| |
| /** |
| * Displays the hover source's tooltip if a tooltip of another source is |
| * currently being displayed. |
| * |
| * @param figureUnderMouse |
| * the figure over which the cursor was when called |
| * @param tip |
| * the tooltip to be displayed |
| * @param eventX |
| * the x coordinate of the cursor |
| * @param eventY |
| * the y coordinate of the cursor |
| * @since 2.0 |
| */ |
| public void updateToolTip(IFigure figureUnderMouse, IFigure tip, |
| int eventX, int eventY) { |
| /* |
| * If the cursor is not on any Figures, it has been moved off of the |
| * control. Hide the tool tip. |
| */ |
| if (figureUnderMouse == null) { |
| if (isShowing()) { |
| hide(); |
| } |
| } |
| // Makes tooltip appear without a hover event if a tip is currently |
| // being displayed |
| if (isShowing() && figureUnderMouse != currentTipSource) { |
| hide(); |
| displayToolTipNear(figureUnderMouse, tip, eventX, eventY); |
| } else if (!isShowing() && figureUnderMouse != currentTipSource) |
| currentTipSource = null; |
| } |
| |
| } |