blob: 98305f712f8bb76eb599e8522bd2496fac4c61ea [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 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.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.swt.SWT;
/**
* 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;
/**
* 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 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() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
hide();
timer.cancel();
}
});
}
}, 5000);
}
}
/**
* Disposes of the tooltip's shell and kills the timer.
*
* @see PopUpHelper#dispose()
*/
public void dispose() {
if (isShowing()) {
timer.cancel();
hide();
}
getShell().dispose();
}
/**
* @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;
// if (timer != null) {
// timer.cancel();
// }
// }
// });
}
/**
* 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();
timer.cancel();
}
}
// Makes tooltip appear without a hover event if a tip is currently
// being displayed
if (isShowing() && figureUnderMouse != currentTipSource) {
hide();
timer.cancel();
displayToolTipNear(figureUnderMouse, tip, eventX, eventY);
} else if (!isShowing() && figureUnderMouse != currentTipSource)
currentTipSource = null;
}
}