]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java
b4e5594a6bddbfd7a386476a94fcbd49f651d228
[simantics/platform.git] / bundles / org.simantics.diagram.connection / src / org / simantics / diagram / connection / rendering / StyledRouteGraphRenderer.java
1 /*******************************************************************************\r
2  * Copyright (c) 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.connection.rendering;\r
13 \r
14 import gnu.trove.set.hash.THashSet;\r
15 \r
16 import java.awt.BasicStroke;\r
17 import java.awt.Color;\r
18 import java.awt.Graphics2D;\r
19 import java.awt.geom.Path2D;\r
20 import java.io.Serializable;\r
21 import java.util.List;\r
22 \r
23 import org.simantics.diagram.connection.RouteGraph;\r
24 import org.simantics.diagram.connection.RouteLine;\r
25 import org.simantics.diagram.connection.RoutePoint;\r
26 import org.simantics.diagram.connection.RouteTerminal;\r
27 import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
28 \r
29 \r
30 public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializable {\r
31 \r
32     private static final BasicStroke GUIDE_LINE_STROKE = new BasicStroke(0.1f);\r
33     private static final Color GUIDE_LINE_COLOR = new Color(255,255,255);\r
34     \r
35         private static final long serialVersionUID = 1564960933064029020L;\r
36 \r
37         protected final ConnectionStyle style;\r
38 \r
39         // Caches to avoid creating new objects all the time during rendering\r
40         protected transient Path2D path;\r
41         protected transient THashSet<RoutePoint> branchPoints;\r
42 \r
43         public StyledRouteGraphRenderer(ConnectionStyle style) {\r
44                 if (style == null)\r
45                         throw new NullPointerException("null style");\r
46                 this.style = style;\r
47         }\r
48 \r
49         public ConnectionStyle getStyle() {\r
50                 return style;\r
51         }\r
52 \r
53         @Override\r
54         public void render(Graphics2D g, RouteGraph rg) {\r
55                 if (path == null)\r
56                         path = new Path2D.Double();\r
57                 path.reset();\r
58                 rg.getPath2D(path);\r
59                 style.drawPath(g, path, false);\r
60 \r
61                 if (branchPoints == null)\r
62                         branchPoints = new THashSet<RoutePoint>();\r
63                 branchPoints.clear();\r
64                 for(RouteLine line : rg.getLines()) {\r
65                     renderLine(g, line, false);\r
66                     collectBranchPoints(line, branchPoints);\r
67                 }\r
68                 for(RouteLine line : rg.getTransientLines()) {\r
69                         renderLine(g, line, true);\r
70                         collectBranchPoints(line, branchPoints);\r
71                 }\r
72 \r
73                 /*for(RouteTerminal terminal : rg.getTerminals())\r
74                         terminal.render(g);*/\r
75                 for(RoutePoint point : branchPoints) {\r
76                         style.drawBranchPoint(g, point.getX(), point.getY());\r
77                 }\r
78         }\r
79         \r
80         private static void collectBranchPoints(RouteLine line, THashSet<RoutePoint> branchPoints) {\r
81                 List<RoutePoint> points = line.getPoints();\r
82                 for(int i=1;i<points.size()-1;++i) {\r
83                         RoutePoint point = points.get(i);\r
84                         branchPoints.add(point);\r
85                 }\r
86         }\r
87         \r
88         private void renderLine(Graphics2D g, RouteLine line, boolean isTransient) {\r
89             if(line.getPoints().size() == 0) {\r
90                 System.err.println("Route line does not contain any points (data = " + line.getData() + ").");\r
91                 return;\r
92             }\r
93                 RoutePoint p1 = line.getBegin();\r
94                 RoutePoint p2 = line.getEnd();\r
95                 double x1 = p1.getX();\r
96                 double y1 = p1.getY();\r
97                 double x2 = p2.getX();\r
98                 double y2 = p2.getY();\r
99                 boolean isHorizontal = line.isHorizontal();\r
100 //              double length = isHorizontal ? x2-x1 : y2-y1; // original length before removing the endpoints\r
101                 if(isHorizontal) {\r
102                         if(p1 instanceof RouteTerminal) {\r
103                                 RouteTerminal terminal = (RouteTerminal)p1;\r
104                                 ILineEndStyle style = terminal.getRenderStyle();\r
105                                 style.render(g, x1, y1, 2);\r
106                                 x1 += style.getLineEndLength(0);\r
107                         }\r
108                         if(p2 instanceof RouteTerminal) {\r
109                                 RouteTerminal terminal = (RouteTerminal)p2;\r
110                                 ILineEndStyle style = terminal.getRenderStyle();\r
111                                 style.render(g, x2, y2, 0);\r
112                                 x2 -= style.getLineEndLength(2);\r
113                         }\r
114                 }\r
115                 else {\r
116                         if(p1 instanceof RouteTerminal) {\r
117                                 RouteTerminal terminal = (RouteTerminal)p1;\r
118                                 ILineEndStyle style = terminal.getRenderStyle();\r
119                                 style.render(g, x1, y1, 3);\r
120                                 y1 += style.getLineEndLength(1);\r
121                         }\r
122                         if(p2 instanceof RouteTerminal) {\r
123                                 RouteTerminal terminal = (RouteTerminal)p2;\r
124                                 ILineEndStyle style = terminal.getRenderStyle();\r
125                                 style.render(g, x2, y2, 1);\r
126                                 y2 -= style.getLineEndLength(3);\r
127                         }\r
128                 }\r
129 //              if(length <= style.getDegeneratedLineLength())\r
130 //                      style.drawDegeneratedLine(g, 0.5*(x1+x2), 0.5*(y1+y2), isHorizontal, isTransient);\r
131 //              else\r
132 //                      style.drawLine(g, x1, y1, x2, y2, isTransient);\r
133         }\r
134         \r
135         @Override\r
136         public void renderGuides(Graphics2D g, RouteGraph rg) {\r
137             Path2D path = new Path2D.Double();\r
138         for(RouteLine line : rg.getLines()) {\r
139             RoutePoint p1 = line.getBegin();\r
140             RoutePoint p2 = line.getEnd();\r
141             double dx = p2.getX() - p1.getX();\r
142             double dy = p2.getY() - p1.getY();\r
143             double adx = Math.abs(dx);\r
144             double ady = Math.abs(dy);\r
145             if(adx > ady) {\r
146                 if(adx > 4)\r
147                     dx = 0.5*dx - Math.signum(dx);\r
148                 else\r
149                     dx *= 0.25;\r
150                 path.moveTo(p1.getX()+dx, p1.getY());\r
151                 path.lineTo(p2.getX()-dx, p2.getY());\r
152             }\r
153             else {\r
154                 if(ady > 4)\r
155                     dy = 0.5*dy - Math.signum(dy);\r
156                 else\r
157                     dy *= 0.25;\r
158                 path.moveTo(p1.getX(), p1.getY()+dy);\r
159                 path.lineTo(p2.getX(), p2.getY()-dy);\r
160             }\r
161         }\r
162         g.setStroke(GUIDE_LINE_STROKE);\r
163         g.setColor(GUIDE_LINE_COLOR);\r
164         g.draw(path);\r
165         }\r
166 \r
167         @Override\r
168         public int hashCode() {\r
169                 return style.hashCode();\r
170         }\r
171 \r
172         @Override\r
173         public boolean equals(Object obj) {\r
174                 if (this == obj)\r
175                         return true;\r
176                 if (obj == null)\r
177                         return false;\r
178                 if (getClass() != obj.getClass())\r
179                         return false;\r
180                 StyledRouteGraphRenderer other = (StyledRouteGraphRenderer) obj;\r
181                 return style.equals(other.style);\r
182         }\r
183 \r
184 }\r