| LayoutContext.java |
1 /****************************************************************************
2 * This demo file is part of yFiles for Java 2.14.
3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4 * 72070 Tuebingen, Germany. All rights reserved.
5 *
6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7 * of demo files in source code or binary form, with or without
8 * modification, is not permitted.
9 *
10 * Owners of a valid software license for a yFiles for Java version that this
11 * demo is shipped with are allowed to use the demo source code as basis
12 * for their own yFiles for Java powered applications. Use of such programs is
13 * governed by the rights and conditions as set out in the yFiles for Java
14 * license agreement.
15 *
16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 ***************************************************************************/
28 package demo.view.graphexplorer;
29
30 import y.base.Edge;
31 import y.base.Node;
32 import y.view.Graph2D;
33 import y.view.Graph2DView;
34
35 import java.util.HashSet;
36 import java.util.Iterator;
37 import java.util.LinkedHashSet;
38 import java.util.Set;
39
40 /**
41 * Encapsulates information about old/removed and new elements for
42 * partial/incremental and complete re-layout.
43 *
44 */
45 final class LayoutContext {
46 private final Graph2DView view;
47 private final boolean animated;
48 private final boolean fromSketch;
49 private final Node fixedNode;
50 private boolean groupingMode ;
51 private final Set newNodes;
52 private final Set newEdges;
53 private final Set oldNodes;
54 private final Set oldEdges;
55 private final Set removedNodes;
56 private final Set removedEdges;
57
58 /**
59 * Initializes a new context object for the specified view.
60 * @param view the view whose associated graph is laid out.
61 * @param animated if <code>true</code> the calculated layout will be applied
62 * in an animated fashion.
63 * @param fromSketch if <code>true</code> an incremental layout should be
64 * calculated.
65 * @param fixedNode specifies a node whose coordinates may not change.
66 * @param groupingMode specifies a node whose coordinates may not change.
67 */
68 LayoutContext(
69 final Graph2DView view,
70 final boolean animated,
71 final boolean fromSketch,
72 final Node fixedNode,
73 final boolean groupingMode
74 ) {
75 this.view = view;
76 this.animated = animated;
77 this.fromSketch = fromSketch;
78 this.fixedNode = fixedNode;
79 this.groupingMode = groupingMode;
80 this.newNodes = new LinkedHashSet();
81 this.newEdges = new LinkedHashSet();
82 this.oldNodes = new HashSet();
83 this.oldEdges = new HashSet();
84 this.removedNodes = new LinkedHashSet();
85 this.removedEdges = new LinkedHashSet();
86 this.groupingMode = groupingMode;
87 }
88
89 /**
90 * Returns the view whose graph is laid out.
91 * @return the view whose graph is laid out.
92 */
93 Graph2DView getView() {
94 return view;
95 }
96
97 /**
98 * Returns the graph that is laid out.
99 * @return the graph that is laid out.
100 */
101 Graph2D getGraph2D() {
102 return view.getGraph2D();
103 }
104
105 /**
106 * Returns a node whose coordinates may not change.
107 * @return a node whose coordinates may not change.
108 */
109 Node getFixedNode() {
110 return fixedNode;
111 }
112
113 /**
114 * Determines whether or not the calculated layout should be applied in an
115 * animated fashion.
116 * @return <code>true</code> if the calculated layout should be applied in an
117 * animated fashion; <code>false</code> otherwise.
118 */
119 public boolean isAnimated() {
120 return animated;
121 }
122
123 /**
124 * Determines whether or not an incremental layout should be calculated.
125 * @return <code>true</code> if an incremental layout should be calculated;
126 * <code>false</code> otherwise.
127 */
128 boolean isFromSketch() {
129 return fromSketch;
130 }
131
132 /**
133 * Marks a node as <em>new</em> for the purpose of layout calculation.
134 * <p>
135 * New nodes are laid out in an optimal way when performing an incremental
136 * layout calculation.
137 * </p>
138 * @param node the node to mark as new.
139 * @see #newNodes()
140 * @see #isNewNode(y.base.Node)
141 */
142 void addNewNode( final Node node ) {
143 newNodes.add(node);
144 }
145
146 /**
147 * Returns an iterator over all nodes marked as <em>new</code>.
148 * <p>
149 * New nodes are laid out in an optimal way when performing an incremental
150 * layout calculation.
151 * </p>
152 * @return an iterator over all nodes marked as <em>new</code>.
153 * @see #addNewNode(y.base.Node)
154 * @see #isNewNode(y.base.Node)
155 */
156 Iterator newNodes() {
157 return newNodes.iterator();
158 }
159
160 /**
161 * Returns whether or not the specified node is marked as <em>new</em>.
162 * <p>
163 * New nodes are laid out in an optimal way when performing an incremental
164 * layout calculation.
165 * </p>
166 * @param node the node to check.
167 * @return <code>true</code> if the specified node is marked as <em>new</em>;
168 * <code>false</code> otherwise.
169 * @see #addNewNode(y.base.Node)
170 * @see #newNodes()
171 */
172 boolean isNewNode( final Node node ) {
173 return newNodes.contains(node);
174 }
175
176 /**
177 * Marks an edge as <em>new</em> for the purpose of layout calculation.
178 * <p>
179 * New edges are laid out in an optimal way when performing an incremental
180 * layout calculation.
181 * </p>
182 * @param edge the edge to mark as new.
183 * @see #newEdges()
184 */
185 void addNewEdge( final Edge edge ) {
186 newEdges.add(edge);
187 }
188
189 /**
190 * Returns an iterator over all edges marked as <em>new</code>.
191 * <p>
192 * New edges are laid out in an optimal way when performing an incremental
193 * layout calculation.
194 * </p>
195 * @return an iterator over all edges marked as <em>new</code>.
196 * @see #addNewEdge(y.base.Edge)
197 */
198 Iterator newEdges() {
199 return newEdges.iterator();
200 }
201
202 /**
203 * Returns whether or not the specified edge is marked as <em>new</em>.
204 * <p>
205 * New edges are laid out in an optimal way when performing an incremental
206 * layout calculation.
207 * </p>
208 * @param edge the edge to check.
209 * @return <code>true</code> if the specified edge is marked as <em>new</em>;
210 * <code>false</code> otherwise.
211 * @see #addNewEdge(y.base.Edge)
212 * @see #newEdges()
213 */
214 boolean isNewEdge( final Edge edge ) {
215 return newEdges.contains(edge);
216 }
217
218
219 /**
220 * Marks a node as <em>old</em> for the purpose of layout calculation.
221 * <p>
222 * If possible, old nodes are not changed when performing an incremental
223 * layout calculation.
224 * </p>
225 * @param node the node to mark as old.
226 * @see #isOldNode(y.base.Node)
227 */
228 void addOldNode( final Node node ) {
229 oldNodes.add(node);
230 }
231
232 /**
233 * Returns whether or not the specified node is marked as <em>old</em>.
234 * <p>
235 * If possible, old nodes are not changed when performing an incremental
236 * layout calculation.
237 * </p>
238 * @param node the node to check.
239 * @return <code>true</code> if the specified node is marked as <em>old</em>;
240 * <code>false</code> otherwise.
241 * @see #addOldNode(y.base.Node)
242 */
243 boolean isOldNode( final Node node ) {
244 return oldNodes.contains(node);
245 }
246
247 /**
248 * Marks an edge as <em>old</em> for the purpose of layout calculation.
249 * <p>
250 * If possible, old edges are not changed when performing an incremental
251 * layout calculation.
252 * </p>
253 * @param edge the edge to mark as old.
254 * @see #isOldEdge(y.base.Edge)
255 */
256 void addOldEdge( final Edge edge ) {
257 oldEdges.add(edge);
258 }
259
260 /**
261 * Returns whether or not the specified edge is marked as <em>old</em>.
262 * <p>
263 * If possible, old edges are not changed when performing an incremental
264 * layout calculation.
265 * </p>
266 * @param edge the edge to check.
267 * @return <code>true</code> if the specified edge is marked as <em>old</em>;
268 * <code>false</code> otherwise.
269 * @see #addOldEdge(y.base.Edge)
270 */
271 boolean isOldEdge( final Edge edge ) {
272 return oldEdges.contains(edge);
273 }
274
275
276 /**
277 * Marks a node for removal after layout calculation.
278 * <p>
279 * Nodes marked for removal are ignored when performing layout calculation
280 * and are faded out during layout change animation.
281 * </p>
282 * @param node the node to mark for removal.
283 * @see #removedNodes()
284 * @see #isRemovedNode(y.base.Node)
285 */
286 void addRemovedNode( final Node node ) {
287 removedNodes.add(node);
288 }
289
290 /**
291 * Returns an iterator over all nodes marked for removal.
292 * <p>
293 * Nodes marked for removal are ignored when performing layout calculation
294 * and are faded out during layout change animation.
295 * </p>
296 * @return an iterator over all nodes marked for removal.
297 * @see #addRemovedNode(y.base.Node)
298 * @see #isRemovedNode(y.base.Node)
299 */
300 Iterator removedNodes() {
301 return removedNodes.iterator();
302 }
303
304 /**
305 * Returns whether or not the specified node is marked for removal.
306 * <p>
307 * Nodes marked for removal are ignored when performing layout calculation
308 * and are faded out during layout change animation.
309 * </p>
310 * @param node the node to check.
311 * @return <code>true</code> if the specified node is marked for removal;
312 * <code>false</code> otherwise.
313 * @see #addRemovedNode(y.base.Node)
314 * @see #removedNodes()
315 */
316 boolean isRemovedNode( final Node node ) {
317 return removedNodes.contains(node);
318 }
319
320 /**
321 * Marks an edge for removal after layout calculation.
322 * <p>
323 * Edges marked for removal are ignored when performing layout calculation
324 * and are faded out during layout change animation.
325 * </p>
326 * @param edge the edge to mark for removal.
327 * @see #removedEdges()
328 * @see #isRemovedEdge(y.base.Edge)
329 */
330 void addRemovedEdge( final Edge edge ) {
331 removedEdges.add(edge);
332 }
333
334 /**
335 * Returns an iterator over all edges marked for removal.
336 * <p>
337 * Edges marked for removal are ignored when performing layout calculation
338 * and are faded out during layout change animation.
339 * </p>
340 * @return an iterator over all edges marked for removal.
341 * @see #addRemovedEdge(y.base.Edge)
342 * @see #isRemovedEdge(y.base.Edge)
343 */
344 Iterator removedEdges() {
345 return removedEdges.iterator();
346 }
347
348 /**
349 * Returns whether or not the specified edge is marked for removal.
350 * <p>
351 * Edge marked for removal are ignored when performing layout calculation
352 * and are faded out during layout change animation.
353 * </p>
354 * @param edge the edge to check.
355 * @return <code>true</code> if the specified edge is marked for removal;
356 * <code>false</code> otherwise.
357 * @see #addRemovedEdge(y.base.Edge)
358 * @see #removedEdges()
359 */
360 boolean isRemovedEdge( final Edge edge ) {
361 return removedEdges.contains(edge);
362 }
363
364 /**
365 * Signals whether or not a layout algorithm shall treat the layout graph as
366 * being grouped.
367 * @return <code>true</code> if a layout algorithm shall treat the layout
368 * graph as being grouped; <code>false</code> otherwise.
369 */
370 public boolean isGroupingMode() {
371 return groupingMode;
372 }
373 }
374