/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.core.tooltips.presenter;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.python.pydev.core.uiutils.UIUtils;
import com.aptana.shared_core.bindings.KeyBindingHelper;
/**
* Shows tooltips as an information presenter, so, links can be added and the user can interact with it.
*
* Based on http://demo.spars.info/j/frameset.cgi?compo_id=146467&q=mouseexit&hl=mouseexit&packagename=org.eclipse.swt.examples.hoverhelp&componame=org.eclipse.swt.examples.hoverhelp.HoverHelp$ToolTipPresenterHandler&CASE=0&MORPHO=1&location=1111111111111111111&ref=1&mode=frameset&LANG=1
*
* Emulated tooltip handler
* Notice that we could display anything in a tooltip besides text and images.
* For instance, it might make sense to embed large tables of data or buttons linking
* data under inspection to material elsewhere, or perform dynamic lookup for creating
* tooltip text on the fly.
*/
public class ToolTipPresenterHandler {
public static final String TIP_DATA = "TIP_DATA";
private Shell tipShell;
private Label tipLabelImage, tipLabelText;
private Widget tipWidget; // widget this tooltip is hovering over
private IInformationPresenterControlManager informationPresenterManager;
private IInformationPresenter presenter;
public ToolTipPresenterHandler(Shell parent) {
this(parent, null);
}
public ToolTipPresenterHandler(Shell parent, IInformationPresenter presenter) {
this(parent, presenter, null);
}
/**
* Creates a new tooltip handler
*
* @param parent the parent Shell
*/
public ToolTipPresenterHandler(Shell parent, IInformationPresenter presenter, String tooltipAffordanceString) {
this.presenter = presenter;
informationPresenterManager = new InformationPresenterControlManager(presenter, tooltipAffordanceString);
}
private void disposeOfCurrentTipShell() {
if (tipShell != null) {
tipShell.dispose();
tipShell = null;
}
tipWidget = null;
}
/**
* Enables customized hover help for a specified control
*
* @control the control on which to enable hoverhelp
*/
public void install(final Control control) {
informationPresenterManager.install(control);
/*
* Get out of the way if we attempt to activate the control underneath the tooltip
*/
control.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
disposeOfCurrentTipShell();
}
});
/*
* Trap hover events to pop-up tooltip
*/
control.addMouseTrackListener(new MouseTrackAdapter() {
public void mouseExit(MouseEvent e) {
disposeOfCurrentTipShell();
}
public void mouseHover(MouseEvent event) {
Point pt = new Point(event.x, event.y);
Widget widget = event.widget;
if (widget instanceof ToolBar) {
ToolBar w = (ToolBar) widget;
widget = w.getItem(pt);
}
if (widget instanceof Table) {
Table w = (Table) widget;
widget = w.getItem(pt);
}
if (widget instanceof Tree) {
Tree w = (Tree) widget;
widget = w.getItem(pt);
}
if (widget == null) {
disposeOfCurrentTipShell();
return;
}
if (widget == tipWidget) {
return;
}
tipWidget = widget;
Object data = widget.getData(TIP_DATA);
if (data == null) {
return;
}
final String text;
if (data instanceof String) {
text = (String) data;
} else {
text = data.toString();
}
if (text == null) {
return;
}
//It must be set before showing the tooltip, as we'll loose the focus to the tooltip and the
//currently active bindings will become inactive.
KeySequence activateEditorBinding = KeyBindingHelper
.getCommandKeyBinding("org.eclipse.ui.window.activateEditor");
informationPresenterManager.setActivateEditorBinding(activateEditorBinding);
Shell activeShell = UIUtils.getActiveShell();
informationPresenterManager.setInitiallyActiveShell(activeShell);
createControls();
final Point pos = new Point(pt.x + 10, pt.y);
ITooltipInformationProvider provider = new ITooltipInformationProvider() {
public Object getInformation(Control fControl) {
return text;
}
public Point getPosition(Control fControl) {
return pos;
}
};
if (presenter instanceof IInformationPresenterAsTooltip) {
IInformationPresenterAsTooltip iInformationPresenterAsTooltip = (IInformationPresenterAsTooltip) presenter;
iInformationPresenterAsTooltip.setData(data);
}
informationPresenterManager.setInformationProvider(provider);
informationPresenterManager.showInformation();
}
});
}
private void createControls() {
Display display = UIUtils.getDisplay();
if (tipShell != null) {
return;
}
tipShell = new Shell(display, SWT.ON_TOP | SWT.TOOL);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
gridLayout.marginWidth = 2;
gridLayout.marginHeight = 2;
tipShell.setLayout(gridLayout);
tipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
tipLabelImage = new Label(tipShell, SWT.NONE);
tipLabelImage.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
tipLabelImage.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
tipLabelImage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
tipLabelText = new Label(tipShell, SWT.NONE);
tipLabelText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
tipLabelText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
tipLabelText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
}
}