]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram.connection / src / org / simantics / diagram / connection / RouteLine.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;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 \r
16 import java.io.PrintStream;\r
17 import java.io.Serializable;\r
18 import java.util.ArrayList;\r
19 import java.util.Collection;\r
20 import java.util.Collections;\r
21 import java.util.List;\r
22 \r
23 import org.simantics.diagram.connection.segments.Segment;\r
24 \r
25 public class RouteLine implements RouteNode, Serializable {\r
26     private static final long serialVersionUID = -7256429294500809465L;\r
27 \r
28     Object data;\r
29     boolean isHorizontal;\r
30     double  position;\r
31     boolean hidden;\r
32     \r
33     ArrayList<RoutePoint> points = new ArrayList<RoutePoint>(4);\r
34     RouteLine nextTransient;\r
35     RouteTerminal terminal;\r
36     \r
37     RouteLine(boolean isHorizontal, double position) {\r
38         this.isHorizontal = isHorizontal;\r
39         this.position = position;\r
40     }\r
41     \r
42     @Override\r
43     public void setData(Object data) {\r
44         this.data = data;\r
45     }\r
46     \r
47     @Override\r
48     public Object getData() {\r
49         return data;\r
50     }\r
51 \r
52     public boolean isHorizontal() {\r
53         return isHorizontal;\r
54     }\r
55     \r
56     public boolean isHidden() {\r
57                 return hidden;\r
58         }\r
59     \r
60     public double getPosition() {\r
61         return position;\r
62     }\r
63     \r
64     public List<RoutePoint> getPoints() {\r
65         if(RouteGraph.RETURN_UNMODIFIABLE_COLLECTIONS)\r
66                 return Collections.unmodifiableList(points);\r
67         else\r
68                 return points;\r
69     }\r
70     \r
71     void addPoint(RoutePoint link) {\r
72         points.add(link);        \r
73     }\r
74 \r
75     void remove() {\r
76         for(RoutePoint point : points)\r
77             point.removeFromOther(this);\r
78     }\r
79     \r
80     void setPointPositions() {        \r
81         if(isHorizontal) {\r
82             for(RoutePoint point : points)\r
83                 point.y = position;\r
84         }\r
85         else {\r
86             for(RoutePoint point : points)\r
87                 point.x = position;\r
88         }\r
89     }\r
90 \r
91     void sortPoints() {\r
92         Collections.sort(points, isHorizontal \r
93                 ? RoutePoint.X_COMPARATOR \r
94                 : RoutePoint.Y_COMPARATOR);\r
95     }\r
96     \r
97     public boolean isNear(double x2, double y2, double tolerance) {\r
98         return isHorizontal \r
99                 ? Math.abs(y2-position) <= tolerance \r
100                     && points.get(0).x <= x2 \r
101                     && x2 <= points.get(points.size()-1).x\r
102                 : Math.abs(x2-position) <= tolerance \r
103                     && points.get(0).y <= y2 \r
104                     && y2 <= points.get(points.size()-1).y;\r
105     }\r
106 \r
107     public void print(PrintStream out) {\r
108         if(isHorizontal)\r
109             out.print("    HOR");\r
110         else\r
111             out.print("    VER");\r
112         for(RoutePoint point : points) {\r
113             out.print(" ("+point.x+","+point.y+")");\r
114         }\r
115         out.print(" (data=" + data + ")");\r
116         out.println();\r
117     }\r
118 \r
119     void setLocation(double x, double y) {\r
120         if(isHorizontal)\r
121             position = y;\r
122         else\r
123             position = x;\r
124     }\r
125 \r
126     public double getLength() {\r
127         if(isHorizontal)\r
128             return points.get(points.size()-1).x - points.get(0).x;\r
129         else\r
130             return points.get(points.size()-1).y - points.get(0).y;\r
131     }\r
132 \r
133     boolean isConnectedToPeristentLine() {\r
134         for(RoutePoint point : points)\r
135             if(point instanceof RouteLink) {\r
136                 RouteLink link = (RouteLink)point;\r
137                 if(link.a == this) {\r
138                     if(!link.b.isTransient())\r
139                         return true;\r
140                 }\r
141                 else {\r
142                     if(!link.a.isTransient())\r
143                         return true;\r
144                 }\r
145             }\r
146         return false;\r
147     }\r
148     \r
149     public RoutePoint getBegin() {\r
150         return points.get(0);\r
151     }\r
152     \r
153     public RoutePoint getEnd() {\r
154         return points.get(points.size()-1);\r
155     }\r
156 \r
157     public boolean isTransient() {\r
158         return terminal != null;\r
159     }\r
160 \r
161     RouteLine copy(THashMap<Object, Object> map) {      \r
162         RouteLine copy = (RouteLine)map.get(this);\r
163         if(copy == null) {\r
164                 copy = new RouteLine(isHorizontal, position);\r
165                 map.put(this, copy);\r
166                 copy.data = data;\r
167                 copy.nextTransient = nextTransient == null ? null : nextTransient.copy(map);\r
168                 copy.terminal = terminal == null ? null : terminal.copy(map);\r
169                 for(RoutePoint point : points)\r
170                         copy.points.add(point.copy(map));\r
171         }\r
172         return copy;\r
173     }\r
174     \r
175     public Collection<RouteLine> getPersistentNeighbors() {\r
176         ArrayList<RouteLine> lines = new ArrayList<RouteLine>();\r
177         for(RoutePoint point : points)\r
178                 if(point instanceof RouteLink) {\r
179                         RouteLink link = (RouteLink)point;\r
180                         RouteLine line = link.getOther(this);\r
181                         if(!line.isTransient())\r
182                                 lines.add(line);\r
183                 }\r
184         return lines;\r
185     }\r
186 \r
187     public RouteTerminal getTerminal() {\r
188         return terminal;\r
189     }\r
190 \r
191     public boolean beginsWithTerminal() {\r
192         RoutePoint begin = points.get(0);\r
193         if(begin == terminal)\r
194             return true;\r
195         else if(begin instanceof RouteLink) {\r
196             RouteLink link = (RouteLink)begin;\r
197             if(link.a == this)\r
198                 return link.b.hasTerminal(link, terminal);\r
199             else\r
200                 return link.a.hasTerminal(link, terminal);\r
201         }\r
202         else\r
203             return false;\r
204     }\r
205 \r
206     private boolean hasTerminal(RouteLink oldLink, RouteTerminal terminal) {\r
207         RoutePoint begin = points.get(0);\r
208         RoutePoint end = points.get(1);\r
209         if(begin == terminal || end == terminal)\r
210             return true;\r
211         if(begin instanceof RouteLink && begin != oldLink) {\r
212             RouteLink link = (RouteLink)begin;\r
213             if(link.a == this)\r
214                 return link.b.hasTerminal(link, terminal);\r
215             else\r
216                 return link.a.hasTerminal(link, terminal);\r
217         }\r
218         else if(end instanceof RouteLink && end != oldLink) {\r
219             RouteLink link = (RouteLink)end;\r
220             if(link.a == this)\r
221                 return link.b.hasTerminal(link, terminal);\r
222             else\r
223                 return link.a.hasTerminal(link, terminal);\r
224         }\r
225         else\r
226             return false;\r
227     }\r
228 \r
229     public boolean isDegenerated() {\r
230         if(points.size() <= 1)\r
231             return true;\r
232         if(isHorizontal)\r
233             return points.get(0).x == points.get(points.size()-1).x;\r
234         else\r
235             return points.get(0).y == points.get(points.size()-1).y;\r
236     }\r
237 \r
238     public void collectSegments(ArrayList<Segment> segments) {\r
239         RoutePoint p0 = points.get(0);\r
240         for(int i=1;i<points.size();++i) {\r
241             RoutePoint p1 = points.get(i);\r
242             segments.add(new Segment(p0, p1));            \r
243             p0 = p1;\r
244         }\r
245     }\r
246 }\r