Mercurial > projects > dwt2
comparison org.eclipse.draw2d/src/org/eclipse/draw2d/AutomaticRouter.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children | dbfb303e8fb0 |
comparison
equal
deleted
inserted
replaced
11:43904fec5dca | 12:bc29606a740c |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2005 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.draw2d.AutomaticRouter; | |
14 | |
15 import java.lang.all; | |
16 | |
17 import org.eclipse.draw2d.geometry.Point; | |
18 import org.eclipse.draw2d.geometry.PointList; | |
19 import org.eclipse.draw2d.internal.MultiValueMap; | |
20 import org.eclipse.draw2d.AbstractRouter; | |
21 import org.eclipse.draw2d.ConnectionRouter; | |
22 import org.eclipse.draw2d.ConnectionAnchor; | |
23 import org.eclipse.draw2d.Connection; | |
24 | |
25 /** | |
26 * An abstract router implementation which detects when multiple connections are | |
27 * overlapping. Two connections overlap if the combination of source and target | |
28 * anchors are equal. Subclasses must implement {@link #handleCollision(PointList, int)} | |
29 * to determine how to avoid the overlap. | |
30 * <p> | |
31 * This router can delegate to another connection router. The wrappered router will route | |
32 * the connections first, after which overlapping will be determined. | |
33 */ | |
34 public abstract class AutomaticRouter | |
35 : AbstractRouter | |
36 { | |
37 | |
38 private ConnectionRouter nextRouter; | |
39 private MultiValueMap connections; | |
40 | |
41 public this(){ | |
42 connections = new MultiValueMap(); | |
43 } | |
44 | |
45 private class HashKey { | |
46 | |
47 private ConnectionAnchor anchor1, anchor2; | |
48 | |
49 this(Connection conn) { | |
50 anchor1 = conn.getSourceAnchor(); | |
51 anchor2 = conn.getTargetAnchor(); | |
52 } | |
53 | |
54 public override int opEquals(Object object) { | |
55 bool isEqual = false; | |
56 HashKey hashKey; | |
57 | |
58 if (auto hashKey = cast(HashKey)object ) { | |
59 ConnectionAnchor hkA1 = hashKey.getFirstAnchor(); | |
60 ConnectionAnchor hkA2 = hashKey.getSecondAnchor(); | |
61 | |
62 isEqual = ((cast(Object)hkA1).opEquals(cast(Object)anchor1) && (cast(Object)hkA2).opEquals(cast(Object)anchor2)) | |
63 || ((cast(Object)hkA1).opEquals(cast(Object)anchor2) && (cast(Object)hkA2).opEquals(cast(Object)anchor1)); | |
64 } | |
65 return isEqual; | |
66 } | |
67 | |
68 public ConnectionAnchor getFirstAnchor() { | |
69 return anchor1; | |
70 } | |
71 | |
72 public ConnectionAnchor getSecondAnchor() { | |
73 return anchor2; | |
74 } | |
75 | |
76 public override hash_t toHash() { | |
77 return (cast(Object)anchor1).toHash() ^ (cast(Object)anchor2).toHash(); | |
78 } | |
79 } | |
80 | |
81 /** | |
82 * @see org.eclipse.draw2d.ConnectionRouter#getConstraint(Connection) | |
83 */ | |
84 public Object getConstraint(Connection connection) { | |
85 if (next() !is null) | |
86 return next().getConstraint(connection); | |
87 return null; | |
88 } | |
89 | |
90 /** | |
91 * Handles collisions between 2 or more Connections. Collisions are currently defined as 2 | |
92 * connections with no bendpoints and whose start and end points coincide. In other | |
93 * words, the 2 connections are the exact same line. | |
94 * | |
95 * @param list The PointList of a connection that collides with another connection | |
96 * @param index The index of the current connection in the list of colliding connections | |
97 */ | |
98 protected abstract void handleCollision(PointList list, int index); | |
99 | |
100 /** | |
101 * @see org.eclipse.draw2d.ConnectionRouter#invalidate(Connection) | |
102 */ | |
103 public void invalidate(Connection conn) { | |
104 if (next() !is null) | |
105 next().invalidate(conn); | |
106 if (conn.getSourceAnchor() is null || conn.getTargetAnchor() is null) | |
107 return; | |
108 HashKey connectionKey = new HashKey(conn); | |
109 ArrayList connectionList = connections.get(connectionKey); | |
110 int affected = connections.remove(connectionKey, cast(Object)conn); | |
111 if (affected !is -1) { | |
112 for (int i = affected; i < connectionList.size(); i++) | |
113 (cast(Connection)connectionList.get(i)).revalidate(); | |
114 } else | |
115 connections.removeValue(cast(Object)conn); | |
116 | |
117 } | |
118 | |
119 /** | |
120 * Returns the next router in the chain. | |
121 * @return The next router | |
122 * @since 2.0 | |
123 */ | |
124 protected ConnectionRouter next() { | |
125 return nextRouter; | |
126 } | |
127 | |
128 | |
129 | |
130 /** | |
131 * @see org.eclipse.draw2d.ConnectionRouter#remove(Connection) | |
132 */ | |
133 public void remove(Connection conn) { | |
134 if (conn.getSourceAnchor() is null || conn.getTargetAnchor() is null) | |
135 return; | |
136 HashKey connectionKey = new HashKey(conn); | |
137 ArrayList connectionList = connections.get(connectionKey); | |
138 if (connectionList !is null) { | |
139 int index = connections.remove(connectionKey,cast(Object) conn); | |
140 for (int i = index + 1; i < connectionList.size(); i++) | |
141 (cast(Connection)connectionList.get(i)).revalidate(); | |
142 } | |
143 if (next() !is null) | |
144 next().remove(conn); | |
145 } | |
146 | |
147 /** | |
148 * Routes the given connection. Calls the 'next' router first (if one exists) and if no | |
149 * bendpoints were added by the next router, collisions are dealt with by calling | |
150 * {@link #handleCollision(PointList, int)}. | |
151 * @param conn The connection to route | |
152 */ | |
153 public void route(Connection conn) { | |
154 if (next() !is null) | |
155 next().route(conn); | |
156 else { | |
157 conn.getPoints().removeAllPoints(); | |
158 setEndPoints(conn); | |
159 } | |
160 | |
161 if (conn.getPoints().size() is 2) { | |
162 PointList points = conn.getPoints(); | |
163 HashKey connectionKey = new HashKey(conn); | |
164 ArrayList connectionList = connections.get(connectionKey); | |
165 | |
166 if (connectionList !is null) { | |
167 | |
168 int index; | |
169 | |
170 if (connectionList.contains(cast(Object)conn)) { | |
171 index = connectionList.indexOf(cast(Object)conn) + 1; | |
172 } else { | |
173 index = connectionList.size() + 1; | |
174 connections.put(connectionKey, cast(Object)conn); | |
175 } | |
176 | |
177 handleCollision(points, index); | |
178 conn.setPoints(points); | |
179 } else { | |
180 connections.put(connectionKey, cast(Object)conn); | |
181 } | |
182 } | |
183 } | |
184 | |
185 /** | |
186 * An AutomaticRouter needs no constraints for the connections it routes. This method | |
187 * invalidates the connections and calls {@link #setConstraint(Connection, Object)} on the | |
188 * {@link #next()} router. | |
189 * @see org.eclipse.draw2d.ConnectionRouter#setConstraint(Connection, Object) | |
190 */ | |
191 public void setConstraint(Connection connection, Object constraint) { | |
192 invalidate(connection); | |
193 if (next() !is null) | |
194 next().setConstraint(connection, constraint); | |
195 } | |
196 | |
197 /** | |
198 * Sets the start and end points for the given connection. | |
199 * @param conn The connection | |
200 */ | |
201 protected void setEndPoints(Connection conn) { | |
202 PointList points = conn.getPoints(); | |
203 points.removeAllPoints(); | |
204 Point start = getStartPoint(conn); | |
205 Point end = getEndPoint(conn); | |
206 conn.translateToRelative(start); | |
207 conn.translateToRelative(end); | |
208 points.addPoint(start); | |
209 points.addPoint(end); | |
210 conn.setPoints(points); | |
211 } | |
212 | |
213 /** | |
214 * Sets the next router. | |
215 * @param router The ConnectionRouter | |
216 * @since 2.0 | |
217 */ | |
218 public void setNextRouter(ConnectionRouter router) { | |
219 nextRouter = router; | |
220 } | |
221 | |
222 } |