package org.eclipse.gmf.tooling.runtime.linklf.policies; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.eclipse.draw2d.AncestorListener; import org.eclipse.draw2d.Bendpoint; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.Ellipse; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; import org.eclipse.swt.graphics.Color; /** * @since 3.3 */ public class DebugShowConnectionEndPointsAndAnchorsEditPolicy extends LinksLFConnectionEndPointEditPolicy { private FeedbackBase mySourceAnchor; private FeedbackBase myTargetAnchor; private List<FeedbackBase> myRoutingConstraint; protected void showAnchors() { if (mySourceAnchor == null) { mySourceAnchor = createSourceAnchorFocus(); } addFeedback(mySourceAnchor); if (myTargetAnchor == null) { myTargetAnchor = createTargetAnchorFocus(); } addFeedback(myTargetAnchor); } protected void showRouting() { if (myRoutingConstraint == null) { myRoutingConstraint = new LinkedList<FeedbackBase>(); if (getConnection().getRoutingConstraint() instanceof List<?>) { @SuppressWarnings("unchecked") List<Bendpoint> bendpoints = (List<Bendpoint>) getConnection() .getRoutingConstraint(); for (int i = 1; i < bendpoints.size() - 1; i++) { RoutingBendpointFeedback feedback = new RoutingBendpointFeedback( getConnection(), i); myRoutingConstraint.add(feedback); addFeedback(feedback); } } } } @Override protected void showSelection() { super.showSelection(); showAnchors(); showRouting(); } @Override protected void hideSelection() { hideRouting(); hideAnchors(); super.hideSelection(); } protected void hideAnchors() { if (mySourceAnchor != null) { removeFeedback(mySourceAnchor); mySourceAnchor = null; } if (myTargetAnchor != null) { removeFeedback(myTargetAnchor); myTargetAnchor = null; } } protected void hideRouting() { if (myRoutingConstraint != null) { for (FeedbackBase next : myRoutingConstraint) { removeFeedback(next); } myRoutingConstraint = null; } } private SourceAnchorFeedback createSourceAnchorFocus() { return new SourceAnchorFeedback(getConnection()); } private TargetAnchorFeedback createTargetAnchorFocus() { return new TargetAnchorFeedback(getConnection()); } public ConnectionEditPart getHost() { return (ConnectionEditPart) super.getHost(); } private static abstract class FeedbackBase extends Ellipse { private AncestorListener myAncestorListener = new AncestorListener.Stub() { public void ancestorMoved(IFigure ancestor) { revalidate(); } }; private Connection myConnection; public FeedbackBase(Connection connection, Color color) { myConnection = connection; setSize(10, 10); setLineWidth(2); setFill(false); setOpaque(true); if (color != null) { setBackgroundColor(color); setForegroundColor(color); } } protected abstract void updateFeedback(); @Override public void addNotify() { super.addNotify(); myConnection.addAncestorListener(myAncestorListener); } @Override public void removeNotify() { myConnection.removeAncestorListener(myAncestorListener); super.removeNotify(); } @Override public void validate() { if (isValid()) { return; } updateFeedback(); } public void showAt(Point point) { Dimension halfSize = getSize().getScaled(-0.5); setLocation(point.getTranslated(halfSize)); } protected Connection getConnection() { return myConnection; } } private static abstract class AnchorFeedback extends FeedbackBase { public AnchorFeedback(Connection connection, Color color) { super(connection, color); } protected abstract ConnectionAnchor getAnchor(Connection connection); @Override protected void updateFeedback() { ConnectionAnchor anchor = getAnchor(getConnection()); Point refPoint = anchor.getReferencePoint().getCopy(); translateToRelative(refPoint); showAt(refPoint); } } private static class SourceAnchorFeedback extends AnchorFeedback { public SourceAnchorFeedback(Connection connection) { super(connection, ColorConstants.blue); } @Override protected ConnectionAnchor getAnchor(Connection connection) { return connection.getSourceAnchor(); } } private static class TargetAnchorFeedback extends AnchorFeedback { public TargetAnchorFeedback(Connection connection) { super(connection, ColorConstants.red); } @Override protected ConnectionAnchor getAnchor(Connection connection) { return connection.getTargetAnchor(); } } private static class RoutingBendpointFeedback extends FeedbackBase { private int myIndex; public RoutingBendpointFeedback(Connection connection, int idx) { super(connection, ColorConstants.green); myIndex = idx; } @Override protected void updateFeedback() { @SuppressWarnings("unchecked") List<Bendpoint> routing = (List<Bendpoint>) getConnection() .getRoutingConstraint(); if (routing == null) { routing = Collections.emptyList(); } Bendpoint bendpoint = null; if (routing.size() > myIndex) { bendpoint = routing.get(myIndex); } if (bendpoint == null) { setVisible(false); } else { setVisible(true); Point point = bendpoint.getLocation().getCopy(); getConnection().translateToAbsolute(point); translateToRelative(point); showAt(point); } } } }