/******************************************************************************* * 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.utils.NodeUtils; import org.eclipse.gef.geometry.convert.fx.FX2Geometry; import org.eclipse.gef.geometry.planar.Point; import org.eclipse.gef.geometry.planar.Rectangle; import org.eclipse.gef.graph.Node; import org.eclipse.gef.mvc.fx.parts.AbstractVisualPart; import org.eclipse.gef.mvc.fx.parts.IVisualPart; import org.eclipse.gef.zest.fx.ZestProperties; import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; import javafx.geometry.Bounds; import javafx.scene.Group; import javafx.scene.text.Text; import javafx.util.Pair; /** * The {@link NodeLabelPart} is an {@link AbstractVisualPart} that is used to * display the external label of a node. * * @author mwienand * */ public class NodeLabelPart extends AbstractLabelPart { @Override public Point computeLabelPosition() { IVisualPart<? extends javafx.scene.Node> firstAnchorage = getFirstAnchorage(); // determine bounds of anchorage visual Rectangle anchorageBounds = NodeUtils .sceneToLocal(getVisual().getParent(), NodeUtils.localToScene(firstAnchorage.getVisual(), FX2Geometry.toRectangle(firstAnchorage.getVisual().getLayoutBounds()))) .getBounds(); // determine text bounds Bounds textBounds = getVisual().getLayoutBounds(); // TODO: compute better label position return new Point(anchorageBounds.getX() + anchorageBounds.getWidth() / 2 - textBounds.getWidth() / 2, anchorageBounds.getY() + anchorageBounds.getHeight()); } @Override protected Group doCreateVisual() { Text text = createText(); Group g = new Group(); g.getStyleClass().add(NodePart.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) { Node node = getContent().getKey(); Map<String, Object> attrs = node.attributesProperty(); if (attrs.containsKey(ZestProperties.EXTERNAL_LABEL_CSS_STYLE__NE)) { String textCssStyle = ZestProperties.getExternalLabelCssStyle(node); getVisual().setStyle(textCssStyle); } String label = ZestProperties.getExternalLabel(node); if (label != null) { getText().setText(label); } IVisualPart<? extends javafx.scene.Node> firstAnchorage = getFirstAnchorage(); if (firstAnchorage == null) { return; } refreshPosition(getVisual(), getLabelPosition()); } @SuppressWarnings("unchecked") @Override public Pair<Node, String> getContent() { return (Pair<Node, String>) super.getContent(); } /** * Returns the {@link NodePart} for which this {@link NodeLabelPart} * displays the label. * * @return The {@link NodePart} for which this {@link NodeLabelPart} * displays the label. */ public IVisualPart<? extends javafx.scene.Node> getFirstAnchorage() { return getAnchoragesUnmodifiable().isEmpty() ? null : (IVisualPart<? extends javafx.scene.Node>) getAnchoragesUnmodifiable().keys().iterator().next(); } }