X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram.connection%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fconnection%2Frendering%2FBasicConnectionStyle.java;h=2f218d8fab325c4c0f7e082a3f977a74fa798486;hp=a8661d324755eb2d99e374088aabe69cd6ec8727;hb=08c2bc8c90c7342582fd792bbeeaa16d6c18f9b1;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07 diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/BasicConnectionStyle.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/BasicConnectionStyle.java index a8661d324..2f218d8fa 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/BasicConnectionStyle.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/BasicConnectionStyle.java @@ -13,10 +13,13 @@ package org.simantics.diagram.connection.rendering; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.awt.Stroke; +import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; import java.io.Serializable; /** @@ -32,18 +35,25 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { final double branchPointRadius; final Stroke lineStroke; final Stroke routeLineStroke; - final double degenerateLineLength; + final double degenerateLineLength; + final double rounding; transient Line2D line = new Line2D.Double(); transient Ellipse2D ellipse = new Ellipse2D.Double(); - public BasicConnectionStyle(Color lineColor, Color branchPointColor, double branchPointRadius, Stroke lineStroke, Stroke routeLineStroke, double degenerateLineLength) { + public BasicConnectionStyle(Color lineColor, Color branchPointColor, double branchPointRadius, Stroke lineStroke, Stroke routeLineStroke, double degenerateLineLength, + double rounding) { this.lineColor = lineColor; this.branchPointColor = branchPointColor; this.branchPointRadius = branchPointRadius; this.lineStroke = lineStroke; this.routeLineStroke = routeLineStroke; this.degenerateLineLength = degenerateLineLength; + this.rounding = rounding; + } + + public BasicConnectionStyle(Color lineColor, Color branchPointColor, double branchPointRadius, Stroke lineStroke, Stroke routeLineStroke, double degenerateLineLength) { + this(lineColor, branchPointColor, branchPointRadius, lineStroke, routeLineStroke, degenerateLineLength, 0.0); } public Color getLineColor() { @@ -88,7 +98,85 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { g.setColor(lineColor); if (lineStroke != null) g.setStroke(lineStroke); - g.draw(path); + if(rounding > 0.0) { + Object oldRenderingHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.draw(round(path)); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldRenderingHint); + } + else + g.draw(path); + } + + private Path2D round(Path2D path) { + Path2D newPath = new Path2D.Double(); + PathIterator it = path.getPathIterator(new AffineTransform()); + double[] coords = new double[6]; + double newX=0.0, newY=0.0; + double curX=0.0, curY=0.0; + double oldX=0.0, oldY=0.0; + int state = 0; + while(!it.isDone()) { + int type = it.currentSegment(coords); + if(type == PathIterator.SEG_LINETO) { + newX = coords[0]; + newY = coords[1]; + if(state == 1) { + double dx1 = curX-oldX; + double dy1 = curY-oldY; + double dx2 = curX-newX; + double dy2 = curY-newY; + double r1 = Math.sqrt(dx1*dx1 + dy1*dy1); + double r2 = Math.sqrt(dx2*dx2 + dy2*dy2); + double maxRadius = 0.5 * Math.min(r1, r2); + double radius = Math.min(rounding, maxRadius); + double dx1Normalized = r1 > 0 ? dx1 / r1 : 0; + double dy1Normalized = r1 > 0 ? dy1 / r1 : 0; + double dx2Normalized = r2 > 0 ? dx2 / r2 : 0; + double dy2Normalized = r2 > 0 ? dy2 / r2 : 0; + newPath.lineTo(curX - radius*dx1Normalized, curY - radius*dy1Normalized); + newPath.curveTo(curX, curY, + curX, curY, + curX - radius*dx2Normalized, curY - radius*dy2Normalized); + } + else + ++state; + oldX = curX; + oldY = curY; + curX = newX; + curY = newY; + } + else { + if(state > 0) { + newPath.lineTo(curX, curY); + state = 0; + } + switch(type) { + case PathIterator.SEG_MOVETO: + curX = coords[0]; + curY = coords[1]; + newPath.moveTo(curX, curY); + break; + case PathIterator.SEG_QUADTO: + curX = coords[2]; + curY = coords[3]; + newPath.quadTo(coords[0], coords[1], coords[2], coords[3]); + break; + case PathIterator.SEG_CUBICTO: + curX = coords[4]; + curY = coords[5]; + newPath.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); + break; + case PathIterator.SEG_CLOSE: + newPath.closePath(); + break; + } + } + it.next(); + } + if(state > 0) + newPath.lineTo(curX, curY); + return newPath; } @Override @@ -130,6 +218,8 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((lineColor == null) ? 0 : lineColor.hashCode()); result = prime * result + ((lineStroke == null) ? 0 : lineStroke.hashCode()); + temp = Double.doubleToLongBits(rounding); + result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((routeLineStroke == null) ? 0 : routeLineStroke.hashCode()); return result; } @@ -162,6 +252,8 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { return false; } else if (!lineStroke.equals(other.lineStroke)) return false; + if (Double.doubleToLongBits(rounding) != Double.doubleToLongBits(other.rounding)) + return false; if (routeLineStroke == null) { if (other.routeLineStroke != null) return false; @@ -170,4 +262,8 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { return true; } + public double getRounding() { + return rounding; + } + }