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=301cfdf092bdabb5ea368c763ada136908e196c6;hp=514eeb92ae3430ce9bd2357b695a8cf0517d70ee;hb=59dd11d2734183c00ea18c25b79a004fba9526ac;hpb=969bd23cab98a79ca9101af33334000879fb60c5 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 514eeb92a..301cfdf09 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 @@ -1,173 +1,265 @@ -/******************************************************************************* - * Copyright (c) 2011 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.diagram.connection.rendering; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Stroke; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.Path2D; -import java.io.Serializable; - -/** - * @author Tuukka Lehtonen - */ -public class BasicConnectionStyle implements ConnectionStyle, Serializable { - - private static final long serialVersionUID = -5799681720482456895L; - - // line thickness in millimeters. - final Color lineColor; - final Color branchPointColor; - final double branchPointRadius; - final Stroke lineStroke; - final Stroke routeLineStroke; - final double degenerateLineLength; - - 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) { - this.lineColor = lineColor; - this.branchPointColor = branchPointColor; - this.branchPointRadius = branchPointRadius; - this.lineStroke = lineStroke; - this.routeLineStroke = routeLineStroke; - this.degenerateLineLength = degenerateLineLength; - } - - public Color getLineColor() { - return lineColor; - } - - public Color getBranchPointColor() { - return branchPointColor; - } - - public double getBranchPointRadius() { - return branchPointRadius; - } - - public Stroke getLineStroke() { - return lineStroke; - } - - public Stroke getRouteLineStroke() { - return routeLineStroke; - } - - @Override - public void drawLine(Graphics2D g, double x1, double y1, double x2, - double y2, boolean isTransient) { - if (lineColor != null) - g.setColor(lineColor); - if(isTransient) { - g.setStroke(lineStroke); - line.setLine(x1, y1, x2, y2); - g.draw(line); - } else { - g.setStroke(routeLineStroke); - line.setLine(x1, y1, x2, y2); - g.draw(line); - } - } - - @Override - public void drawPath(Graphics2D g, Path2D path, boolean isTransient) { - if (lineColor != null) - g.setColor(lineColor); - if (lineStroke != null) - g.setStroke(lineStroke); - g.draw(path); - } - - @Override - public void drawBranchPoint(Graphics2D g, double x, double y) { - g.setColor(branchPointColor); - double r = branchPointRadius; - double d = 2*r; - ellipse.setFrame(x-r, y-r, d, d); - g.fill(ellipse); - } - - @Override - public void drawDegeneratedLine(Graphics2D g, double x, double y, - boolean isHorizontal, boolean isTransient) { - double d = getDegeneratedLineLength()*0.5; - if(isHorizontal) { - line.setLine(x-d, y, x+d, y); - g.draw(line); - } else { - line.setLine(x, y-d, x, y+d); - g.draw(line); - } - } - - @Override - public double getDegeneratedLineLength() { - return degenerateLineLength; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((branchPointColor == null) ? 0 : branchPointColor.hashCode()); - long temp; - temp = Double.doubleToLongBits(branchPointRadius); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(degenerateLineLength); - result = prime * result + (int) (temp ^ (temp >>> 32)); - result = prime * result + ((lineColor == null) ? 0 : lineColor.hashCode()); - result = prime * result + ((lineStroke == null) ? 0 : lineStroke.hashCode()); - result = prime * result + ((routeLineStroke == null) ? 0 : routeLineStroke.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BasicConnectionStyle other = (BasicConnectionStyle) obj; - if (branchPointColor == null) { - if (other.branchPointColor != null) - return false; - } else if (!branchPointColor.equals(other.branchPointColor)) - return false; - if (Double.doubleToLongBits(branchPointRadius) != Double.doubleToLongBits(other.branchPointRadius)) - return false; - if (Double.doubleToLongBits(degenerateLineLength) != Double.doubleToLongBits(other.degenerateLineLength)) - return false; - if (lineColor == null) { - if (other.lineColor != null) - return false; - } else if (!lineColor.equals(other.lineColor)) - return false; - if (lineStroke == null) { - if (other.lineStroke != null) - return false; - } else if (!lineStroke.equals(other.lineStroke)) - return false; - if (routeLineStroke == null) { - if (other.routeLineStroke != null) - return false; - } else if (!routeLineStroke.equals(other.routeLineStroke)) - return false; - return true; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +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; + +/** + * @author Tuukka Lehtonen + */ +public class BasicConnectionStyle implements ConnectionStyle, Serializable { + + private static final long serialVersionUID = -5799681720482456895L; + + // line thickness in millimeters. + final Color lineColor; + final Color branchPointColor; + final double branchPointRadius; + final Stroke lineStroke; + final Stroke routeLineStroke; + 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, + 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() { + return lineColor; + } + + public Color getBranchPointColor() { + return branchPointColor; + } + + public double getBranchPointRadius() { + return branchPointRadius; + } + + public Stroke getLineStroke() { + return lineStroke; + } + + public Stroke getRouteLineStroke() { + return routeLineStroke; + } + + @Override + public void drawLine(Graphics2D g, double x1, double y1, double x2, + double y2, boolean isTransient) { + if (lineColor != null) + g.setColor(lineColor); + if(isTransient) { + g.setStroke(lineStroke); + line.setLine(x1, y1, x2, y2); + g.draw(line); + } else { + g.setStroke(routeLineStroke); + line.setLine(x1, y1, x2, y2); + g.draw(line); + } + } + + @Override + public void drawPath(Graphics2D g, Path2D path, boolean isTransient) { + if (lineColor != null) + g.setColor(lineColor); + if (lineStroke != null) + g.setStroke(lineStroke); + 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 + public void drawBranchPoint(Graphics2D g, double x, double y) { + g.setColor(branchPointColor); + double r = branchPointRadius; + double d = 2*r; + ellipse.setFrame(x-r, y-r, d, d); + g.fill(ellipse); + } + + @Override + public void drawDegeneratedLine(Graphics2D g, double x, double y, + boolean isHorizontal, boolean isTransient) { + double d = getDegeneratedLineLength()*0.5; + if(isHorizontal) { + line.setLine(x-d, y, x+d, y); + g.draw(line); + } else { + line.setLine(x, y-d, x, y+d); + g.draw(line); + } + } + + @Override + public double getDegeneratedLineLength() { + return degenerateLineLength; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((branchPointColor == null) ? 0 : branchPointColor.hashCode()); + long temp; + temp = Double.doubleToLongBits(branchPointRadius); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(degenerateLineLength); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + ((lineColor == null) ? 0 : lineColor.hashCode()); + result = prime * result + ((lineStroke == null) ? 0 : lineStroke.hashCode()); + result = prime * result + ((routeLineStroke == null) ? 0 : routeLineStroke.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BasicConnectionStyle other = (BasicConnectionStyle) obj; + if (branchPointColor == null) { + if (other.branchPointColor != null) + return false; + } else if (!branchPointColor.equals(other.branchPointColor)) + return false; + if (Double.doubleToLongBits(branchPointRadius) != Double.doubleToLongBits(other.branchPointRadius)) + return false; + if (Double.doubleToLongBits(degenerateLineLength) != Double.doubleToLongBits(other.degenerateLineLength)) + return false; + if (lineColor == null) { + if (other.lineColor != null) + return false; + } else if (!lineColor.equals(other.lineColor)) + return false; + if (lineStroke == null) { + if (other.lineStroke != null) + return false; + } else if (!lineStroke.equals(other.lineStroke)) + return false; + if (routeLineStroke == null) { + if (other.routeLineStroke != null) + return false; + } else if (!routeLineStroke.equals(other.routeLineStroke)) + return false; + return true; + } + + public double getRounding() { + return rounding; + } + +}