package org.archstudio.bna.things.shapes; import java.awt.Shape; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.List; import org.archstudio.bna.IBNAView; import org.archstudio.bna.ICoordinate; import org.archstudio.bna.ICoordinateMapper; import org.archstudio.bna.constants.ArrowheadShape; import org.archstudio.bna.things.AbstractThingPeer; import org.archstudio.bna.ui.IUIResources; import org.archstudio.bna.utils.BNAUtils; import org.archstudio.bna.utils.ShapeUtils; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; public class SplineThingPeer<T extends SplineThing> extends AbstractThingPeer<T> { public SplineThingPeer(T thing, IBNAView view, ICoordinateMapper cm) { super(thing, view, cm); } protected Shape createLocalShape() { Path2D localShape = new Path2D.Double(); List<? extends Point2D> points = t.getPoints(); Point2D point = cm.worldToLocal(points.get(0)); localShape.moveTo(point.getX(), point.getY()); for (int i = 1; i < points.size(); i++) { point = cm.worldToLocal(points.get(i)); localShape.lineTo(point.getX(), point.getY()); } return localShape; } @Override public boolean draw(Rectangle localBounds, IUIResources r) { Rectangle lbb = cm.worldToLocal(t.getBoundingBox()); lbb.width += 2; lbb.height += 2; if (!localBounds.intersects(lbb)) { return false; } List<Point2D> points = BNAUtils.worldToLocalPoint2D(cm, t.getPoints()); Shape localShape = createLocalShape(); ArrowheadShape arrowhead1 = (t.getArrowhead1Color() != null || t.getArrowhead1EdgeColor() != null) && t.getArrowhead1Shape() != ArrowheadShape.NONE ? t.getArrowhead1Shape() : ArrowheadShape.NONE; Shape localArrowhead1 = ShapeUtils.createArrowhead(arrowhead1, points.get(0), points.get(1), t.getArrowhead1Width(), t.getArrowhead1Length()); ArrowheadShape arrowhead2 = (t.getArrowhead2Color() != null || t.getArrowhead2EdgeColor() != null) && t.getArrowhead2Shape() != ArrowheadShape.NONE ? t.getArrowhead2Shape() : ArrowheadShape.NONE; Shape localArrowhead2 = ShapeUtils.createArrowhead(arrowhead2, points.get(points.size() - 1), points.get(points.size() - 2), t.getArrowhead2Width(), t.getArrowhead2Length()); RGB glowColor = t.getGlowColor(); if (glowColor != null) { r.glowShape(localShape, glowColor, t.getGlowWidth(), t.getGlowAlpha()); if (arrowhead1 != ArrowheadShape.NONE) { r.glowShape(localArrowhead1, glowColor, t.getGlowWidth(), t.getGlowAlpha()); } if (arrowhead2 != ArrowheadShape.NONE) { r.glowShape(localArrowhead2, glowColor, t.getGlowWidth(), t.getGlowAlpha()); } } { RGB arrowhead1Color = arrowhead1.isFilled() ? t.getArrowhead1Color() : null; if (arrowhead1Color != null) { r.fillShape(localArrowhead1, arrowhead1Color, null, 1); } RGB arrowhead2Color = arrowhead2.isFilled() ? t.getArrowhead2Color() : null; if (arrowhead2Color != null) { r.fillShape(localArrowhead2, arrowhead2Color, null, 1); } } if (t.isSelected()) { int offset = t.getRotatingOffset(); r.selectShape(localShape, offset); if (arrowhead1.isEdged()) { r.selectShape(localArrowhead1, offset); } if (arrowhead2.isEdged()) { r.selectShape(localArrowhead2, offset); } } else { r.drawShape(localShape, t.getEdgeColor(), t.getLineWidth(), t.getLineStyle(), 1); RGB arrowhead1Color = arrowhead1.isEdged() ? t.getArrowhead1EdgeColor() : null; if (arrowhead1Color != null) { r.drawShape(localArrowhead1, arrowhead1Color, t.getLineWidth(), t.getLineStyle(), 1); } RGB arrowhead2Color = arrowhead2.isEdged() ? t.getArrowhead2EdgeColor() : null; if (arrowhead2Color != null) { r.drawShape(localArrowhead2, arrowhead2Color, t.getLineWidth(), t.getLineStyle(), 1); } } return true; } @Override public boolean isInThing(ICoordinate location) { Rectangle lbb = cm.worldToLocal(t.getBoundingBox()); lbb.x -= BNAUtils.LINE_CLICK_DISTANCE; lbb.y -= BNAUtils.LINE_CLICK_DISTANCE; lbb.width += BNAUtils.LINE_CLICK_DISTANCE * 2; lbb.height += BNAUtils.LINE_CLICK_DISTANCE * 2; Point lp = location.getLocalPoint(); if (lbb.contains(lp)) { Point2D cp = BNAUtils.getClosestPointOnShape(createLocalShape(), lp.x, lp.y); if (Point2D.distanceSq(lp.x, lp.y, cp.getX(), cp.getY()) <= BNAUtils.LINE_CLICK_DISTANCE * BNAUtils.LINE_CLICK_DISTANCE) { return true; } } return false; } }