/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.ui.livegraph.views; import java.util.HashMap; import java.util.Iterator; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.graph.DirectedGraph; import org.eclipse.draw2d.graph.DirectedGraphLayout; import org.eclipse.draw2d.graph.Edge; import org.eclipse.draw2d.graph.Node; import org.eclipse.swt.SWT; import org.eclipse.zest.layouts.algorithms.DirectedGraphLayoutAlgorithm; import org.eclipse.zest.layouts.dataStructures.InternalNode; import org.eclipse.zest.layouts.dataStructures.InternalRelationship; /** * Based on {@link DirectedGraphLayout} with modifications * * @author Leo Dos Santos */ public class ExtendedDirectedGraphLayoutAlgorithm extends DirectedGraphLayoutAlgorithm { public ExtendedDirectedGraphLayoutAlgorithm(int styles) { super(styles); } @Override protected void applyLayoutInternal(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double boundsX, double boundsY, double boundsWidth, double boundsHeight) { HashMap<InternalNode, Node> mapping = new HashMap<InternalNode, Node>(entitiesToLayout.length); // Difference from DGLA; use the unmodified Draw2D DirectedGraph since // the extended one from the superclass does not handle the horizontal // use case properly. DirectedGraph graph = new DirectedGraph(); for (InternalNode internalNode : entitiesToLayout) { Node node = new Node(internalNode); // Difference from DGLA; get the height/width from the InternalNode // and apply it to the Draw2D Node. Take orientation into account. int height = new Double(internalNode.getHeightInLayout()).intValue(); int width = new Double(internalNode.getWidthInLayout()).intValue(); if ((layout_styles & SWT.HORIZONTAL) == SWT.HORIZONTAL) { node.setSize(new Dimension(height, width)); } else { node.setSize(new Dimension(width, height)); } // End difference from DGLA mapping.put(internalNode, node); graph.nodes.add(node); } for (InternalRelationship relationship : relationshipsToConsider) { Node source = mapping.get(relationship.getSource()); Node dest = mapping.get(relationship.getDestination()); if (source != null && dest != null) { Edge edge = new Edge(relationship, source, dest); graph.edges.add(edge); } } DirectedGraphLayout directedGraphLayout = new DirectedGraphLayout(); directedGraphLayout.visit(graph); for (Iterator<Node> iterator = graph.nodes.iterator(); iterator.hasNext();) { Node node = iterator.next(); InternalNode internalNode = (InternalNode) node.data; // For horizontal layout transpose the x and y coordinates if ((layout_styles & SWT.HORIZONTAL) == SWT.HORIZONTAL) { internalNode.setInternalLocation(node.y, node.x); } else { internalNode.setInternalLocation(node.x, node.y); } } updateLayoutLocations(entitiesToLayout); } }