]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/BasicConnectionStyle.java
Take rounding field into account in equals and in hashCode
[simantics/platform.git] / bundles / org.simantics.diagram.connection / src / org / simantics / diagram / connection / rendering / BasicConnectionStyle.java
index a8661d324755eb2d99e374088aabe69cd6ec8727..2f218d8fab325c4c0f7e082a3f977a74fa798486 100644 (file)
@@ -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;
+    }
+
 }