blob: e9d3e5d9ef15315cd6a8132d69951e087cb5a86d [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.gef.internal.ui.palette.editparts;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.rap.swt.SWT;
class EditPartTipHelper extends org.eclipse.draw2d.PopUpHelper {
private static EditPartTipHelper currentHelper;
private ShellListener shellListener;
private static void setHelper(EditPartTipHelper helper) {
if (currentHelper != null && currentHelper != helper
&& currentHelper.isShowing())
currentHelper.hide();
currentHelper = helper;
}
public EditPartTipHelper(Control c) {
super(c, SWT.ON_TOP | SWT.TOOL | SWT.NO_TRIM);
}
/**
* Sets the LightWeightSystem object's contents to the passed tooltip, and
* displays the tip at the coordianates specified by tipPosX and tipPosY.
* The given coordinates will be adjusted if the tip cannot be completely
* visible on the screen.
*
* @param tip
* The tool tip to be displayed.
* @param tipPosX
* X coordiante of tooltip to be displayed
* @param tipPosY
* Y coordinate of tooltip to be displayed
*/
public void displayToolTipAt(IFigure tip, int tipPosX, int tipPosY) {
if (tip != null) {
// Adjust the position if the tip will not be completely visible on
// the screen
int shiftX = 0;
int shiftY = 0;
Dimension tipSize = tip.getPreferredSize();
getShell();
tipSize = tipSize.getExpanded(getShellTrimSize());
org.eclipse.swt.graphics.Rectangle area = control.getDisplay()
.getClientArea();
org.eclipse.swt.graphics.Point end = new org.eclipse.swt.graphics.Point(
tipPosX + tipSize.width, tipPosY + tipSize.height);
if (!area.contains(end)) {
shiftX = end.x - (area.x + area.width);
shiftY = end.y - (area.y + area.height);
shiftX = shiftX < 0 ? 0 : shiftX;
shiftY = shiftY < 0 ? 0 : shiftY;
}
tipPosX -= shiftX;
tipPosY -= shiftY;
// Display the tip
EditPartTipHelper.setHelper(this);
getLightweightSystem().setContents(tip);
setShellBounds(tipPosX, tipPosY, tipSize.width, tipSize.height);
show();
// UNSUPPORTED - api not implemented in RAP
// getShell().setCapture(true);
}
}
public void dispose() {
if (shellListener != null) {
control.getShell().removeShellListener(shellListener);
shellListener = null;
}
super.dispose();
}
/**
* @see org.eclipse.draw2d.PopUpHelper#hide()
*/
protected void hide() {
super.hide();
currentHelper = null;
}
protected void hookShellListeners() {
/*
* If the cursor leaves the tip window, hide the tooltip and dispose of
* its shell
*/
// UNSUPPORTED - api not implemented in RAP
// getShell().addMouseTrackListener(new MouseTrackAdapter() {
// public void mouseExit(MouseEvent e) {
// getShell().setCapture(false);
// dispose();
// }
// });
/*
* If the mouseExit listener does not get called, dispose of the shell
* if the cursor is no longer in the tooltip. This occurs in the rare
* case that a mouseEnter is not received on the tooltip when it
* appears.
*/
// UNSUPPORTED - api not implemented in RAP
// getShell().addMouseMoveListener(new MouseMoveListener() {
// public void mouseMove(MouseEvent e) {
// Point eventPoint = getShell().toDisplay(new Point(e.x, e.y));
// if (!getShell().getBounds().contains(eventPoint)) {
// if (isShowing())
// getShell().setCapture(false);
// dispose();
// }
// }
// });
// This is to dispose of the tooltip when the user ALT-TABs to another
// window.
if (shellListener == null) {
shellListener = new ShellAdapter() {
public void shellDeactivated(ShellEvent event) {
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
Shell active = Display.getCurrent()
.getActiveShell();
if (getShell() == active
|| control.getShell() == active
|| getShell().isDisposed())
return;
// UNSUPPORTED - api not implemented in RAP
// if (isShowing())
// getShell().setCapture(false);
dispose();
}
});
}
};
control.getShell().addShellListener(shellListener);
getShell().addShellListener(shellListener);
}
/*
* Workaround for GTK Bug - Control.setCapture(boolean) not implemented:
* If the cursor is not over the shell when it is first painted, hide
* the tooltip and dispose of the shell.
*/
if (SWT.getPlatform().equals("gtk")) { //$NON-NLS-1$
getShell().addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
Point cursorLoc = Display.getCurrent().getCursorLocation();
if (!getShell().getBounds().contains(cursorLoc)) {
// This must be run asynchronously. If not, other paint
// listeners may attempt to paint on a disposed control.
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
// UNSUPPORTED - api not implemented in RAP
// if (isShowing())
// getShell().setCapture(false);
dispose();
}
});
}
}
});
}
}
public static boolean isCurrent(EditPartTipHelper helper) {
return currentHelper != null && helper == currentHelper;
}
}