blob: e0a062153a0ae4933a6a5c8aa98421ef11629074 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 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);
}
}