From: Hannu Niemistö Date: Tue, 2 May 2017 17:04:35 +0000 (+0300) Subject: (refs #7177) Rounded connections X-Git-Tag: v1.29.0~83 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=32a6aa7b656804c95b8a2a2df06900955c6df44b (refs #7177) Rounded connections Adds HasRounding property to G2D that rounds connections in the diagrams. Change-Id: I2f5429f90e926b9569633056d50a233cf9f4c395 --- 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..b2895fb34 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,83 @@ 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 maxRadius = 0.5 * Math.min(Math.sqrt(dx1*dx1 + dy1*dy1), Math.sqrt(dx2*dx2 + dy2*dy2)); + double radius = Math.min(rounding, maxRadius); + newPath.lineTo(curX + radius*Math.signum(oldX-curX), curY + radius*Math.signum(oldY-curY)); + newPath.curveTo(curX, curY, + curX, curY, + curX + radius*Math.signum(newX-curX), curY + radius*Math.signum(newY-curY)); + + //newPath.lineTo(curX + round*Math.signum(oldX-curX), curY + round*Math.signum(oldY-curY)); + //newPath.lineTo(curX + round*Math.signum(newX-curX), curY + round*Math.signum(newY-curY)); + //newPath.lineTo(curX, curY); + } + 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 @@ -170,4 +256,8 @@ public class BasicConnectionStyle implements ConnectionStyle, Serializable { return true; } + public double getRounding() { + return rounding; + } + } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/RouteGraphUtils.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/RouteGraphUtils.java index 99d9acb70..60f7a09db 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/RouteGraphUtils.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/RouteGraphUtils.java @@ -564,7 +564,7 @@ public class RouteGraphUtils { Color branchPointColor = Color.BLACK; double branchPointRadius = 0.5; double degenerateLineLength = 0.8; - + Color lineColor = cv != null ? cv.toColor() : null; if (lineColor == null) lineColor = Color.DARK_GRAY; @@ -572,6 +572,7 @@ public class RouteGraphUtils { if (lineStroke == null) lineStroke = new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, null, 0); Stroke routeLineStroke = GeometryUtils.scaleStrokeWidth(lineStroke, 2); + double rounding = cv.rounding == null ? 0.0 : cv.rounding; return new BasicConnectionStyle( lineColor, @@ -579,7 +580,8 @@ public class RouteGraphUtils { branchPointRadius, lineStroke, routeLineStroke, - degenerateLineLength); + degenerateLineLength, + rounding); } public static void scheduleSynchronize(Session session, Resource connection, RouteGraphChangeEvent event) { diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/connection/ConnectionVisuals.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/connection/ConnectionVisuals.java index 5aa8048ac..45e407906 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/connection/ConnectionVisuals.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/connection/ConnectionVisuals.java @@ -25,13 +25,15 @@ public class ConnectionVisuals { public final float[] color; public final StrokeType strokeType; public final Stroke stroke; + public final Double rounding; - public ConnectionVisuals(float[] color, StrokeType strokeType, Stroke stroke) { + public ConnectionVisuals(float[] color, StrokeType strokeType, Stroke stroke, Double rounding) { if (color != null && color.length < 3) throw new IllegalArgumentException("colors must have at least 3 components (rgb), got " + color.length); this.color = color; this.strokeType = strokeType; this.stroke = stroke; + this.rounding = rounding; } public Color toColor() { @@ -47,6 +49,7 @@ public class ConnectionVisuals { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(color); + result = prime * result + ((rounding == null) ? 0 : rounding.hashCode()); result = prime * result + ((stroke == null) ? 0 : stroke.hashCode()); result = prime * result + ((strokeType == null) ? 0 : strokeType.hashCode()); return result; @@ -58,20 +61,22 @@ public class ConnectionVisuals { return true; if (obj == null) return false; - if (!(obj instanceof ConnectionVisuals)) + if (getClass() != obj.getClass()) return false; ConnectionVisuals other = (ConnectionVisuals) obj; if (!Arrays.equals(color, other.color)) return false; + if (rounding == null) { + if (other.rounding != null) + return false; + } else if (!rounding.equals(other.rounding)) + return false; if (stroke == null) { if (other.stroke != null) return false; } else if (!stroke.equals(other.stroke)) return false; - if (strokeType == null) { - if (other.strokeType != null) - return false; - } else if (!strokeType.equals(other.strokeType)) + if (strokeType != other.strokeType) return false; return true; } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/query/ConnectionVisualsRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/query/ConnectionVisualsRequest.java index 3e70f1210..4af440a52 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/query/ConnectionVisualsRequest.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/query/ConnectionVisualsRequest.java @@ -52,8 +52,9 @@ public class ConnectionVisualsRequest extends ResourceRead { StrokeType strokeType = toStrokeType(g.getPossibleObject(structuralConnectionType, g2d.HasStrokeType)); Stroke stroke = G2DUtils.getStroke(g, g.getPossibleObject(structuralConnectionType, g2d.HasStroke)); - - return new ConnectionVisuals(color, strokeType, stroke); + Double rounding = g.getPossibleRelatedValue(structuralConnectionType, g2d.HasRounding, Bindings.DOUBLE); + + return new ConnectionVisuals(color, strokeType, stroke, rounding); } StrokeType toStrokeType(Resource strokeType) { diff --git a/bundles/org.simantics.g2d.ontology/graph.tg b/bundles/org.simantics.g2d.ontology/graph.tg index b75d2eb3a..a9eea99f0 100644 Binary files a/bundles/org.simantics.g2d.ontology/graph.tg and b/bundles/org.simantics.g2d.ontology/graph.tg differ diff --git a/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph b/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph index cb458bed2..fc58ade46 100644 --- a/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph +++ b/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph @@ -92,6 +92,8 @@ G2D.StrokeType L0.Double G2D.LineEnd