blob: 59d5fc56c6c9b09f2a15a19c442fa1fdc570024d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 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.swt.examples.hoverhelp;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
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.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
/**
* This example demonstrates how to implement hover help feedback
* using the MouseTrackListener.
*/
public class HoverHelp {
private static ResourceBundle resourceBundle = ResourceBundle.getBundle("examples_hoverhelp");
static final int
hhiInformation = 0,
hhiWarning = 1;
static final String[] imageLocations = {
"information.gif",
"warning.gif"
};
Image images[];
/**
* Runs main program.
*/
public static void main (String [] args) {
Display display = new Display();
Shell shell = new HoverHelp().open(display);
// Event loop
while (shell != null && ! shell.isDisposed()) {
if (! display.readAndDispatch()) display.sleep();
}
// Cleanup
display.dispose();
}
/**
* Opens the main program.
*/
public Shell open(Display display) {
// Load the images
Class<HoverHelp> clazz = HoverHelp.class;
try {
if (images == null) {
images = new Image[imageLocations.length];
for (int i = 0; i < imageLocations.length; ++i) {
InputStream stream = clazz.getResourceAsStream(imageLocations[i]);
ImageData source = new ImageData(stream);
ImageData mask = source.getTransparencyMask();
images[i] = new Image(display, source, mask);
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (Exception ex) {
System.err.println(getResourceString("error.CouldNotLoadResources",
new Object[] { ex.getMessage() }));
return null;
}
// Create the window
Shell shell = new Shell();
createPartControl(shell);
shell.addDisposeListener(e -> {
/* Free resources */
if (images != null) {
for (int i = 0; i < images.length; i++) {
final Image image = images[i];
if (image != null) image.dispose();
}
images = null;
}
});
shell.pack();
shell.open();
return shell;
}
/**
* Gets a string from the resource bundle.
* We don't want to crash because of a missing String.
* Returns the key if not found.
*/
public String getResourceString(String key) {
try {
return resourceBundle.getString(key);
} catch (MissingResourceException e) {
return key;
} catch (NullPointerException e) {
return "!" + key + "!";
}
}
/**
* Gets a string from the resource bundle and binds it
* with the given arguments. If the key is not found,
* return the key.
*/
public String getResourceString(String key, Object[] args) {
try {
return MessageFormat.format(getResourceString(key), args);
} catch (MissingResourceException e) {
return key;
} catch (NullPointerException e) {
return "!" + key + "!";
}
}
/**
* Creates the example
*/
public void createPartControl(Composite frame) {
final ToolTipHandler tooltip = new ToolTipHandler(frame.getShell());
GridLayout layout = new GridLayout();
layout.numColumns = 3;
frame.setLayout(layout);
String platform = SWT.getPlatform();
String helpKey = "F1";
if (platform.equals("gtk")) helpKey = "Ctrl+F1";
if (platform.equals("cocoa")) helpKey = "Help";
ToolBar bar = new ToolBar (frame, SWT.BORDER);
for (int i=0; i<5; i++) {
ToolItem item = new ToolItem (bar, SWT.PUSH);
item.setText (getResourceString("ToolItem.text", new Object[] { Integer.valueOf(i) }));
item.setData ("TIP_TEXT", getResourceString("ToolItem.tooltip",
new Object[] { item.getText(), helpKey }));
item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() {
@Override
public String getHelpText(Widget widget) {
Item item = (Item) widget;
return getResourceString("ToolItem.help", new Object[] { item.getText() });
}
});
}
GridData gridData = new GridData();
gridData.horizontalSpan = 3;
bar.setLayoutData(gridData);
tooltip.activateHoverHelp(bar);
Table table = new Table (frame, SWT.BORDER);
for (int i=0; i<4; i++) {
TableItem item = new TableItem (table, SWT.PUSH);
item.setText (getResourceString("Item", new Object[] { Integer.valueOf(i) }));
item.setData ("TIP_IMAGE", images[hhiInformation]);
item.setText (getResourceString("TableItem.text", new Object[] { Integer.valueOf(i) }));
item.setData ("TIP_TEXT", getResourceString("TableItem.tooltip",
new Object[] { item.getText(), helpKey }));
item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() {
@Override
public String getHelpText(Widget widget) {
Item item = (Item) widget;
return getResourceString("TableItem.help", new Object[] { item.getText() });
}
});
}
table.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL));
tooltip.activateHoverHelp(table);
Tree tree = new Tree (frame, SWT.BORDER);
for (int i=0; i<4; i++) {
TreeItem item = new TreeItem (tree, SWT.PUSH);
item.setText (getResourceString("Item", new Object[] { Integer.valueOf(i) }));
item.setData ("TIP_IMAGE", images[hhiWarning]);
item.setText (getResourceString("TreeItem.text", new Object[] { Integer.valueOf(i) }));
item.setData ("TIP_TEXT", getResourceString("TreeItem.tooltip",
new Object[] { item.getText(), helpKey}));
item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() {
@Override
public String getHelpText(Widget widget) {
Item item = (Item) widget;
return getResourceString("TreeItem.help", new Object[] { item.getText() });
}
});
}
tree.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL));
tooltip.activateHoverHelp(tree);
Button button = new Button (frame, SWT.PUSH);
button.setText (getResourceString("Hello.text"));
button.setData ("TIP_TEXT", getResourceString("Hello.tooltip"));
tooltip.activateHoverHelp(button);
}
/**
* 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.
*/
protected static class ToolTipHandler {
private Shell parentShell;
private Shell tipShell;
private Label tipLabelImage, tipLabelText;
private Widget tipWidget; // widget this tooltip is hovering over
private Point tipPosition; // the position being hovered over
/**
* Creates a new tooltip handler
*
* @param parent the parent Shell
*/
public ToolTipHandler(Shell parent) {
final Display display = parent.getDisplay();
this.parentShell = parent;
tipShell = new Shell(parent, 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));
}
/**
* Enables customized hover help for a specified control
*
* @control the control on which to enable hoverhelp
*/
public void activateHoverHelp(final Control control) {
/*
* Get out of the way if we attempt to activate the control underneath the tooltip
*/
control.addMouseListener(new MouseAdapter () {
@Override
public void mouseDown (MouseEvent e) {
if (tipShell.isVisible()) tipShell.setVisible(false);
}
});
/*
* Trap hover events to pop-up tooltip
*/
control.addMouseTrackListener(new MouseTrackAdapter () {
@Override
public void mouseExit(MouseEvent e) {
if (tipShell.isVisible()) tipShell.setVisible(false);
tipWidget = null;
}
@Override
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) {
tipShell.setVisible(false);
tipWidget = null;
return;
}
if (widget == tipWidget) return;
tipWidget = widget;
tipPosition = control.toDisplay(pt);
String text = (String) widget.getData("TIP_TEXT");
Image image = (Image) widget.getData("TIP_IMAGE");
tipLabelText.setText(text != null ? text : "");
tipLabelImage.setImage(image); // accepts null
tipShell.pack();
setHoverLocation(tipShell, tipPosition);
tipShell.setVisible(true);
}
});
/*
* Trap F1 Help to pop up a custom help box
*/
control.addHelpListener(event -> {
if (tipWidget == null) return;
ToolTipHelpTextHandler handler = (ToolTipHelpTextHandler)
tipWidget.getData("TIP_HELPTEXTHANDLER");
if (handler == null) return;
String text = handler.getHelpText(tipWidget);
if (text == null) return;
if (tipShell.isVisible()) {
tipShell.setVisible(false);
Shell helpShell = new Shell(parentShell, SWT.SHELL_TRIM);
helpShell.setLayout(new FillLayout());
Label label = new Label(helpShell, SWT.NONE);
label.setText(text);
helpShell.pack();
setHoverLocation(helpShell, tipPosition);
helpShell.open();
}
});
}
/**
* Sets the location for a hovering shell
* @param shell the object that is to hover
* @param position the position of a widget to hover over
* @return the top-left location for a hovering box
*/
private void setHoverLocation(Shell shell, Point position) {
Rectangle displayBounds = shell.getDisplay().getBounds();
Rectangle shellBounds = shell.getBounds();
shellBounds.x = Math.max(Math.min(position.x, displayBounds.width - shellBounds.width), 0);
shellBounds.y = Math.max(Math.min(position.y + 16, displayBounds.height - shellBounds.height), 0);
shell.setBounds(shellBounds);
}
}
/**
* ToolTip help handler
*/
protected interface ToolTipHelpTextHandler {
/**
* Get help text
* @param widget the widget that is under help
* @return a help text string
*/
public String getHelpText(Widget widget);
}
}