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