/******************************************************************************* | |
* Copyright (c) 2009, 2011 Mia-Software and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v20.html | |
* | |
* Contributors: | |
* Nicolas Bros (Mia-Software) - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.modisco.infra.browser.editors; | |
import java.util.List; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.modisco.infra.browser.MoDiscoBrowserPlugin; | |
import org.eclipse.modisco.infra.browser.uicore.internal.CustomTreePainter; | |
import org.eclipse.modisco.infra.browser.uicore.internal.CustomTreePainter.StickerToPaint; | |
import org.eclipse.modisco.infra.browser.uicore.internal.model.ModelElementItem; | |
import org.eclipse.modisco.infra.facet.Facet; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.graphics.Point; | |
import org.eclipse.swt.graphics.Rectangle; | |
import org.eclipse.swt.layout.FillLayout; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.swt.widgets.Event; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.Listener; | |
import org.eclipse.swt.widgets.Shell; | |
import org.eclipse.swt.widgets.Tree; | |
import org.eclipse.swt.widgets.TreeItem; | |
/** | |
* Add a tooltip to the tree, that appears when the mouse hovers over a facet | |
* "sticker", to display the name of this facet. Cannot use standard tree | |
* tooltips here, because these can only be defined for an entire tree, and not | |
* for single items. | |
* <p> | |
* caveat: since these tooltips are hand-built, they don't look native on | |
* Windows Vista or 7 | |
*/ | |
public final class FacetTooltip { | |
// TODO: extend | |
// org.eclipse.modisco.infra.common.ui.internal.controls.Tooltip | |
private static final String TREEITEM_DATA_KEY = "_TREEITEM"; //$NON-NLS-1$ | |
public static FacetTooltip create(final Tree tree, final CustomTreePainter customTreePainter) { | |
return new FacetTooltip(tree, customTreePainter); | |
} | |
private FacetTooltip(final Tree tree, final CustomTreePainter customTreePainter) { | |
tree.setToolTipText(""); //$NON-NLS-1$ | |
addTooltip(tree, customTreePainter); | |
} | |
private Shell fTip = null; | |
private Label fLabel = null; | |
private void addTooltip(final Tree tree, final CustomTreePainter customTreePainter) { | |
final Listener treeListener = new Listener() { | |
public void handleEvent(final Event event) { | |
switch (event.type) { | |
case SWT.Dispose: | |
case SWT.KeyDown: | |
case SWT.MouseMove: | |
if (FacetTooltip.this.fTip == null) { | |
break; | |
} | |
FacetTooltip.this.fTip.dispose(); | |
FacetTooltip.this.fTip = null; | |
FacetTooltip.this.fLabel = null; | |
break; | |
case SWT.MouseHover: | |
Display display = Display.getCurrent(); | |
TreeItem item = null; | |
item = tree.getItem(new Point(event.x, event.y)); | |
if (item != null) { | |
Object data = item.getData(); | |
if (data instanceof ModelElementItem) { | |
ModelElementItem modelElementItem = (ModelElementItem) data; | |
EObject eObject = modelElementItem.getEObject(); | |
Rectangle bounds = item.getBounds(); | |
int maxX = tree.getClientArea().width | |
+ tree.getHorizontalBar().getSelection(); | |
List<StickerToPaint> stickersToPaint = customTreePainter | |
.getStickersToPaintFor(eObject, bounds.x, bounds.width, bounds.y, | |
bounds.height, maxX); | |
Facet facet = findFacetAt(event.x, event.y, stickersToPaint); | |
if (facet != null) { | |
createTooltip(display, facet.getName()); | |
FacetTooltip.this.fLabel.setData(FacetTooltip.TREEITEM_DATA_KEY, | |
item); | |
} | |
} | |
} | |
break; | |
default: | |
MoDiscoBrowserPlugin.logError("Unhandled event"); //$NON-NLS-1$ | |
} | |
} | |
}; | |
tree.addListener(SWT.Dispose, treeListener); | |
tree.addListener(SWT.KeyDown, treeListener); | |
tree.addListener(SWT.MouseMove, treeListener); | |
tree.addListener(SWT.MouseHover, treeListener); | |
} | |
private void addMouseExitListener(final Label label) { | |
Listener labelListener = new Listener() { | |
public void handleEvent(final Event event) { | |
Shell shell = label.getShell(); | |
shell.dispose(); | |
} | |
}; | |
label.addListener(SWT.MouseExit, labelListener); | |
} | |
private Facet findFacetAt(final int x, final int y, final List<StickerToPaint> stickersToPaint) { | |
for (StickerToPaint stickerToPaint : stickersToPaint) { | |
Rectangle bounds = stickerToPaint.getBounds(); | |
if (x >= bounds.x && x < bounds.x + bounds.width && y >= bounds.y | |
&& y < bounds.y + bounds.height) { | |
Facet facet = stickerToPaint.getFacet(); | |
if (facet != null) { | |
return facet; | |
} | |
} | |
} | |
return null; | |
} | |
private void createTooltip(final Display display, final String text) { | |
if (this.fTip != null && !this.fTip.isDisposed()) { | |
this.fTip.dispose(); | |
} | |
this.fTip = new Shell(display.getActiveShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); | |
this.fTip.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); | |
FillLayout layout = new FillLayout(); | |
layout.marginWidth = 2; | |
this.fTip.setLayout(layout); | |
this.fLabel = new Label(this.fTip, SWT.NONE); | |
this.fLabel.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); | |
this.fLabel.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); | |
this.fLabel.setText(text); | |
addMouseExitListener(this.fLabel); | |
Point size = this.fTip.computeSize(SWT.DEFAULT, SWT.DEFAULT); | |
Point pt = display.getCursorLocation(); | |
final int verticalCursorOffset = 10; | |
pt.y -= size.y + verticalCursorOffset; | |
// move the tooltip into the visible area of the screen | |
Rectangle clientArea = Display.getCurrent().getClientArea(); | |
if (pt.x + size.x > clientArea.width) { | |
pt.x = clientArea.width - size.x; | |
} | |
if (pt.y + size.y > clientArea.height) { | |
pt.y = clientArea.height - size.y; | |
} | |
this.fTip.setBounds(pt.x, pt.y, size.x, size.y); | |
this.fTip.setVisible(true); | |
} | |
} |