/** * 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)); } }