/*******************************************************************************
* Copyright (c) 2017 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:
* Alexander Nyßen (itemis AG) - initial API & implementation
*
*******************************************************************************/
package org.eclipse.gef.zest.fx.parts;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.gef.fx.anchors.DynamicAnchor.AnchorageReferenceGeometry;
import org.eclipse.gef.fx.anchors.DynamicAnchor.AnchoredReferencePoint;
import org.eclipse.gef.fx.anchors.IComputationStrategy;
import org.eclipse.gef.fx.anchors.ProjectionStrategy;
import org.eclipse.gef.fx.nodes.Connection;
import org.eclipse.gef.geometry.convert.fx.FX2Geometry;
import org.eclipse.gef.geometry.convert.fx.Geometry2FX;
import org.eclipse.gef.geometry.planar.IGeometry;
import org.eclipse.gef.geometry.planar.Line;
import org.eclipse.gef.geometry.planar.Point;
import org.eclipse.gef.mvc.fx.parts.DefaultSelectionFeedbackPartFactory;
import org.eclipse.gef.mvc.fx.parts.IFeedbackPart;
import org.eclipse.gef.mvc.fx.parts.IFeedbackPartFactory;
import org.eclipse.gef.mvc.fx.parts.IVisualPart;
import org.eclipse.gef.mvc.fx.parts.SelectionLinkFeedbackPart;
import org.eclipse.gef.zest.fx.ZestProperties;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import javafx.scene.Node;
/**
* A specific {@link IFeedbackPartFactory} for selection feedback.
*
* @author anyssen
*/
public class ZestFxSelectionFeedbackPartFactory extends DefaultSelectionFeedbackPartFactory {
@Inject
private Injector injector;
@Override
protected IFeedbackPart<? extends Node> createLinkFeedbackPart(IVisualPart<? extends Node> anchorage,
Provider<? extends IGeometry> anchorageLinkFeedbackGeometryProvider, IVisualPart<? extends Node> anchored,
Provider<? extends IGeometry> anchoredLinkFeedbackGeometryProvider, String role) {
// only show link feedback when anchored is no connection
if (!(anchored.getVisual() instanceof Connection)) {
Provider<IGeometry> linkFeedbackGeometryProvider = new Provider<IGeometry>() {
// TODO (#471628): inject; maybe extend IComputationStrategy
// interface
private final ProjectionStrategy computationStrategy = new ProjectionStrategy();
private Point computePosition(EdgePart anchorage, String role) {
Point position = null;
if (ZestProperties.LABEL__NE.equals(role)) {
position = anchorage.getVisual().getCenter();
} else if (ZestProperties.EXTERNAL_LABEL__NE.equals(role)) {
position = anchorage.getVisual().getCenter();
} else if (ZestProperties.SOURCE_LABEL__E.equals(role)) {
position = anchorage.getVisual().getStartPoint();
} else if (ZestProperties.TARGET_LABEL__E.equals(role)) {
position = anchorage.getVisual().getEndPoint();
} else {
throw new IllegalArgumentException("Unsupported role " + role);
}
return FX2Geometry.toPoint(anchorage.getVisual().localToScene(Geometry2FX.toFXPoint(position)));
}
private Point computePosition(Node n1, IGeometry n1Geometry, Node n2, Point n2RefPoint) {
// TODO: let computation strategy initialize the
// parameters, then populate them
Set<IComputationStrategy.Parameter<?>> parameters = new HashSet<>();
parameters.add(new AnchorageReferenceGeometry(n1Geometry));
parameters.add(new AnchoredReferencePoint(n2RefPoint));
return computationStrategy.computePositionInScene(n1, n2, parameters);
}
@Override
public IGeometry get() {
// get anchored visual and geometry
Node anchoredVisual = anchored.getVisual();
IGeometry anchoredGeometryInLocal = anchoredLinkFeedbackGeometryProvider.get();
// get anchorage visual and geometry
Node anchorageVisual = anchorage.getVisual();
IGeometry anchorageGeometryInLocal = anchorageLinkFeedbackGeometryProvider.get();
// determine link target point
Point targetPointInScene = anchored instanceof EdgeLabelPart
? computePosition((EdgePart) anchorage, role)
: computePosition(anchorageVisual, anchorageGeometryInLocal, anchoredVisual,
anchoredGeometryInLocal.getBounds().getCenter());
// determine link source point
Point sourcePointInScene = computePosition(anchoredVisual, anchoredGeometryInLocal, anchorageVisual,
FX2Geometry.toPoint(
(anchorageVisual.sceneToLocal(Geometry2FX.toFXPoint(targetPointInScene)))));
// construct link line
return new Line(sourcePointInScene, targetPointInScene);
}
};
SelectionLinkFeedbackPart part = injector.getInstance(SelectionLinkFeedbackPart.class);
part.setGeometryProvider(linkFeedbackGeometryProvider);
return part;
}
return null;
}
}