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