/*******************************************************************************
* Copyright (c) 2015, 2016 itemis AG 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:
* Matthias Wienand (itemis AG) - initial API & implementation
*
*******************************************************************************/
package org.eclipse.gef.zest.fx.parts;
import java.util.Map;
import org.eclipse.gef.fx.nodes.Connection;
import org.eclipse.gef.fx.utils.NodeUtils;
import org.eclipse.gef.geometry.euclidean.Vector;
import org.eclipse.gef.geometry.planar.Point;
import org.eclipse.gef.graph.Edge;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.zest.fx.ZestProperties;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import javafx.scene.Group;
import javafx.scene.text.Text;
import javafx.util.Pair;
/**
* The {@link EdgeLabelPart} is an {@link AbstractLabelPart} that is used to
* display the label of an edge.
*
* @author mwienand
*
*/
public class EdgeLabelPart extends AbstractLabelPart {
@Override
public Point computeLabelPosition() {
Point position = null;
String value = getContent().getValue();
if (ZestProperties.LABEL__NE.equals(value)) {
position = getMidPoint();
} else if (ZestProperties.EXTERNAL_LABEL__NE.equals(value)) {
position = getMidPoint();
} else if (ZestProperties.SOURCE_LABEL__E.equals(value)) {
position = getStartPoint();
} else if (ZestProperties.TARGET_LABEL__E.equals(value)) {
position = getEndPoint();
}
return position;
}
@Override
protected Group doCreateVisual() {
Text text = createText();
Group g = new Group();
g.getStyleClass().add(EdgePart.CSS_CLASS);
g.getChildren().add(text);
return g;
}
@Override
protected SetMultimap<? extends Object, String> doGetContentAnchorages() {
SetMultimap<Object, String> contentAnchorages = HashMultimap.create();
contentAnchorages.put(getContent().getKey(), getContent().getValue());
return contentAnchorages;
}
@Override
protected void doRefreshVisual(Group visual) {
Edge edge = getContent().getKey();
Map<String, Object> attrs = edge.attributesProperty();
// label or external label (depends on which element we control)
if (ZestProperties.LABEL__NE.equals(getContent().getValue())) {
String label = ZestProperties.getLabel(edge);
if (label != null) {
getText().setText(label);
}
if (attrs.containsKey(ZestProperties.LABEL_CSS_STYLE__NE)) {
String textCssStyle = ZestProperties.getLabelCssStyle(edge);
getVisual().setStyle(textCssStyle);
}
} else if (ZestProperties.EXTERNAL_LABEL__NE.equals(getContent().getValue())) {
String label = ZestProperties.getExternalLabel(edge);
if (label != null) {
getText().setText(label);
}
if (attrs.containsKey(ZestProperties.EXTERNAL_LABEL_CSS_STYLE__NE)) {
String textCssStyle = ZestProperties.getExternalLabelCssStyle(edge);
getVisual().setStyle(textCssStyle);
}
} else if (ZestProperties.SOURCE_LABEL__E.equals(getContent().getValue())) {
String label = ZestProperties.getSourceLabel(edge);
if (label != null) {
getText().setText(label);
}
if (attrs.containsKey(ZestProperties.SOURCE_LABEL_CSS_STYLE__E)) {
String textCssStyle = ZestProperties.getSourceLabelCssStyle(edge);
getVisual().setStyle(textCssStyle);
}
} else if (ZestProperties.TARGET_LABEL__E.equals(getContent().getValue())) {
String label = ZestProperties.getTargetLabel(edge);
if (label != null) {
getText().setText(label);
}
if (attrs.containsKey(ZestProperties.TARGET_LABEL_CSS_STYLE__E)) {
String textCssStyle = ZestProperties.getTargetLabelCssStyle(edge);
getVisual().setStyle(textCssStyle);
}
}
// XXX: We may be refreshed before being anchored on the anchorage.
if (getFirstAnchorage() == null) {
return;
}
refreshPosition(getVisual(), getLabelPosition());
}
@SuppressWarnings("unchecked")
@Override
public Pair<Edge, String> getContent() {
return (Pair<Edge, String>) super.getContent();
}
/**
* Computes the end position for placing a label. The position is
* interpreted in the parent coordinate system of this part's visual.
*
* @return The end position for placing a label.
*/
protected Point getEndPoint() {
Connection connection = getFirstAnchorage().getVisual();
Point endPoint = connection.getEndPoint();
Vector v = new Vector(endPoint, connection.getStartPoint());
if (!v.isNull()) {
v = v.getNormalized().getMultiplied(getText().getLayoutBounds().getHeight());
}
return NodeUtils.sceneToLocal(getVisual().getParent(),
NodeUtils.localToScene(connection, endPoint.getTranslated(v.x, v.y)));
}
/**
* Returns the {@link IContentPart} for which this {@link EdgeLabelPart}
* displays the label.
*
* @return The {@link IContentPart} for which this {@link EdgeLabelPart}
* displays the label.
*/
@SuppressWarnings("unchecked")
protected IContentPart<? extends Connection> getFirstAnchorage() {
return getAnchoragesUnmodifiable().isEmpty() ? null
: (IContentPart<? extends Connection>) getAnchoragesUnmodifiable().keys().iterator().next();
}
/**
* Computes the middle position for placing a label. The position is
* interpreted in the parent coordinate system of this part's visual.
*
* @return The middle position for placing a label.
*/
protected Point getMidPoint() {
Connection connection = getFirstAnchorage().getVisual();
Point midPoint = connection.getCenter();
return NodeUtils.sceneToLocal(getVisual().getParent(), NodeUtils.localToScene(connection, midPoint));
}
/**
* Computes the start position for placing a label. The position is
* interpreted in the parent coordinate system of this part's visual.
*
* @return The start position for placing a label.
*/
protected Point getStartPoint() {
Connection connection = getFirstAnchorage().getVisual();
Point startPoint = connection.getStartPoint();
Vector v = new Vector(startPoint, connection.getEndPoint());
if (!v.isNull()) {
v = v.getNormalized().getMultiplied(getText().getLayoutBounds().getHeight());
}
return NodeUtils.sceneToLocal(getVisual().getParent(),
NodeUtils.localToScene(connection, startPoint.getTranslated(v.x, v.y)));
}
}