package org.xmind.ui.internal.decorations; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Rectangle; import org.xmind.gef.draw2d.decoration.ICorneredDecoration; import org.xmind.gef.draw2d.geometry.Geometry; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.gef.draw2d.graphics.Path; public class RoundedRectBalloonCalloutBranchConnection extends AbstractCalloutBranchConnection implements ICorneredDecoration { public static final int OFFSET = 10; private int cornerSize = 0; public RoundedRectBalloonCalloutBranchConnection() { super(); } public RoundedRectBalloonCalloutBranchConnection(String id) { super(id); } @Override protected void route(IFigure figure, Path shape) { PrecisionPoint p1 = getSourcePosition(figure); PrecisionPoint p2 = getTargetPosition(figure); int corner = getCornerSize(); Rectangle r = getTargetAnchor().getOwner().getBounds(); r = getOutlineBox(r); if (getSourceAnchor() != null) { PrecisionPoint rp = getSourceAnchor().getReferencePoint(); p2 = Geometry.getChopBoxLocation(rp.x, rp.y, r, 0); } int side = Geometry.getSide(p2.x, p2.y, r); shape.moveTo(p2); if (side == Geometry.SIDE_ONE) { shape.lineTo(p1); double delta = p2.x - r.x - OFFSET - corner; if (delta >= 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, r.y); shape.lineTo(p3); shape.lineTo(r.x + corner, r.y); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); } else { PrecisionPoint p3 = new PrecisionPoint(r.x, r.y - delta); shape.lineTo(p3); } shape.lineTo(r.x, r.y + r.height - corner); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 180, 90); shape.lineTo(r.x + r.width - corner, r.y + r.height); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, 90); shape.lineTo(r.x + r.width, r.y + corner); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 0, 90); shape.lineTo(p2); } else if (side == Geometry.SIDE_TWO) { shape.lineTo(p1); double delta = r.getTopRight().x - p2.x - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, r.y); shape.lineTo(p3); shape.lineTo(r.x + r.width - corner, r.y); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 90, -90); } else { PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, p2.y - delta); shape.lineTo(p3); } shape.lineTo(r.getTopRight().x, r.y + r.height - corner); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, -90); shape.lineTo(r.x + corner, r.y + r.height); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, -90); shape.lineTo(r.x, r.y + corner); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); shape.lineTo(p2); } else if (side == Geometry.SIDE_THREE) { double delta = p2.y - r.getTopRight().y - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, p2.y - OFFSET); shape.lineTo(p1); shape.lineTo(p3); shape.lineTo(r.x + r.width, r.y + corner); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 0, 90); } else { PrecisionPoint p3 = new PrecisionPoint( r.getTopRight().x + delta, r.y); shape.lineTo(p1); shape.lineTo(p3); } shape.lineTo(r.x + corner, r.y); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); shape.lineTo(r.x, r.y + r.height - corner); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 180, 90); shape.lineTo(r.x + r.width - corner, r.y + r.height); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, 90); shape.lineTo(p2); } else if (side == Geometry.SIDE_FOUR) { double delta = r.getBottomRight().y - p2.y - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(r.getTopRight().x, p2.y + OFFSET); shape.lineTo(p1); shape.lineTo(p3); shape.lineTo(r.x + r.width, r.y + r.height - corner); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, -90); } else { PrecisionPoint p3 = new PrecisionPoint( r.getBottomRight().x + delta, r.getBottomRight().y); shape.lineTo(p1); shape.lineTo(p3); } shape.lineTo(r.x + corner, r.y + r.height); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, -90); shape.lineTo(r.x, r.y + corner); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); shape.lineTo(r.x + r.width - corner, r.y); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 90, -90); shape.lineTo(p2); } else if (side == Geometry.SIDE_FIVE) { double delta = r.getBottomRight().x - p2.x - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x + OFFSET, p2.y); shape.lineTo(p1); shape.lineTo(p3); shape.lineTo(r.x + r.width - corner, r.y + r.height); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, 90); } else { PrecisionPoint p3 = new PrecisionPoint(r.getBottomRight().x, r.getBottomRight().y + delta); shape.lineTo(p1); shape.lineTo(p3); } shape.lineTo(r.x + r.width, r.y + corner); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 0, 90); shape.lineTo(r.x + corner, r.y); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); shape.lineTo(r.x, r.y + r.height - corner); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 180, 90); shape.lineTo(p2); } else if (side == Geometry.SIDE_SIX) { double delta = p2.x - r.getBottomLeft().x - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x - OFFSET, p2.y); shape.lineTo(p1); shape.lineTo(p3); shape.lineTo(r.x + corner, r.y + r.height); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, -90); } else { PrecisionPoint p3 = new PrecisionPoint(r.getBottomLeft().x, r.getBottomLeft().y + delta); shape.lineTo(p1); shape.lineTo(p3); } shape.lineTo(r.x, r.y + corner); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); shape.lineTo(r.x + r.width - corner, r.y); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 90, -90); shape.lineTo(r.getTopRight().x, r.y + r.height - corner); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, -90); shape.lineTo(p2); } else if (side == Geometry.SIDE_SEVEN) { double delta = r.getBottomLeft().y - p2.y - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y + OFFSET); shape.lineTo(p1); shape.lineTo(p3); shape.lineTo(r.x, r.y + r.height - corner); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 180, 90); } else { PrecisionPoint p3 = new PrecisionPoint( r.getBottomLeft().x - delta, r.getBottomLeft().y); shape.lineTo(p1); shape.lineTo(p3); } shape.lineTo(r.x + r.width - corner, r.y + r.height); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, 90); shape.lineTo(r.x + r.width, r.y + corner); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 0, 90); shape.lineTo(r.x + corner, r.y); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 90, 90); shape.lineTo(p2); } else if (side == Geometry.SIDE_EIGHT) { shape.lineTo(p1); double delta = p2.y - r.y - OFFSET - corner; if (delta > 0) { PrecisionPoint p3 = new PrecisionPoint(p2.x, p2.y - OFFSET); shape.lineTo(p3); shape.lineTo(r.x, r.y + corner); shape.addArc(r.x, r.y, 2 * corner, 2 * corner, 180, -90); } else { PrecisionPoint p3 = new PrecisionPoint(r.x - delta, r.y); shape.lineTo(p3); } shape.lineTo(r.x + r.width - corner, r.y); shape.addArc(r.x + r.width - 2 * corner, r.y, 2 * corner, 2 * corner, 90, -90); shape.lineTo(r.getTopRight().x, r.y + r.height - corner); shape.addArc(r.x + r.width - 2 * corner, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, 0, -90); shape.lineTo(r.x + corner, r.y + r.height); shape.addArc(r.x, r.y + r.height - 2 * corner, 2 * corner, 2 * corner, -90, -90); shape.lineTo(p2); } shape.close(); } public int getCornerSize() { return cornerSize; } public void setCornerSize(IFigure figure, int cornerSize) { if (cornerSize == this.cornerSize) return; this.cornerSize = cornerSize; invalidate(); if (figure != null) { figure.revalidate(); figure.repaint(); } } }