X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fnodes%2FDistrictNetworkEdgeArrayNode.java;fp=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fnodes%2FDistrictNetworkEdgeArrayNode.java;h=c387c435f4b9babda1b020f9e03c85fd017fc595;hb=47a6ef4077aacf0ac5753ee568183bbed5d27411;hp=0000000000000000000000000000000000000000;hpb=adaf5cd394f4a08ea8e692377d24d2611c28f954;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeArrayNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeArrayNode.java new file mode 100644 index 00000000..c387c435 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeArrayNode.java @@ -0,0 +1,104 @@ +package org.simantics.district.network.ui.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.district.network.ui.styles.DistrictNetworkStaticInfoStyle; +import org.simantics.scenegraph.ParentNode; +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.utils.datastructures.Pair; + +public class DistrictNetworkEdgeArrayNode extends G2DNode implements DeferredNode { + + private static final long serialVersionUID = -8377444630205663419L; + + public static final String NODE_KEY = "DISTRICT_NETWORK_EDGE_ARRAY"; + + private static final String RENDERER_ID = "edgeArrayDeferredRenderer"; + + private DistrictNetworkEdgeNode edgeNode = null; + private Double arrowLength; + private Path2D arrowPath; + + @Override + public void render(Graphics2D g2d) { + ParentNode root = (ParentNode) NodeUtil.getNearestParentOfType(this, RTreeNode.class); + DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkStaticInfoStyle.STATIC_INFO_DEFERRED) : null; + if (deferred != null) + deferred.deferNode(g2d.getTransform(), this); + else + renderDeferred(g2d); + } + + @Override + public void renderDeferred(Graphics2D g2d) { + + // Draw arrow + if (arrowLength != null) { + double scale = DistrictNetworkEdgeNode.scaleStroke ? (Double) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_SCALE_UNDER_SPATIAL_ROOT) : 1.0; + g2d.setColor(Color.BLACK); + float lw = DistrictNetworkEdgeNode.STROKE.getLineWidth() / (float)scale; + g2d.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + + double l = arrowLength; + double w = 2 * (double) lw * Math.signum(l); + if (Math.abs(w) > Math.abs(l)) w = l; + double offset = 2 * (double) lw; + + int zoomLevel = (Integer) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_ZOOM_LEVEL); + + Point2D centerPoint = edgeNode.getCenterPoint(zoomLevel); + Point2D direction = edgeNode.getDirection(zoomLevel); + double centerX = centerPoint.getX(), centerY = centerPoint.getY(); + double deltaX = direction.getX(), deltaY = direction.getY(); + + // Ensure the line is always rendered on top of the edge + // to prevent overlap with static info rendered below it. + double odx = offset * deltaY; + double ody = offset * deltaX; + if (odx < 0) { + odx = -odx; + ody = -ody; + } + + double x0 = centerX - l/2 * deltaX + ody; + double y0 = centerY - l/2 * deltaY - odx; + double x1 = centerX + (l/2 - w) * deltaX + ody; + double y1 = centerY + (l/2 - w) * deltaY - odx; + + g2d.draw(new Line2D.Double(x0, y0, x1, y1)); + + arrowPath = new Path2D.Double(); + arrowPath.moveTo(x1 + w * deltaX, y1 + w * deltaY); + arrowPath.lineTo(x1 + w * deltaY, y1 - w * deltaX); + arrowPath.lineTo(x1 - w * deltaY, y1 + w * deltaX); + arrowPath.closePath(); + g2d.fill(arrowPath); + } + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + public void setEdgeNode(DistrictNetworkEdgeNode edgeNode) { + this.edgeNode = edgeNode; + } + + public void setArrowLength(Double length) { + this.arrowLength = length; + } + + public static Pair> renderer() { + return Pair.make(RENDERER_ID, DeferredRenderingNode.class); + } + +}