/****************************************************************************** * Copyright (c) 2008 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.draw2d.ui.graph; import java.util.Iterator; import org.eclipse.draw2d.graph.CompoundDirectedGraph; import org.eclipse.draw2d.graph.DirectedGraph; import org.eclipse.draw2d.graph.Edge; import org.eclipse.draw2d.graph.Node; import org.eclipse.draw2d.graph.Rank; /** * Class containing graph utility methods used internally * * @author aboyko * @since 2.1 */ class GraphUtilities { static void transpose(DirectedGraph g) { for (int i = 0; i < g.nodes.size(); i++) { transpose(g.nodes.getNode(i)); } for (int i = 0; i < g.edges.size(); i++) { transpose(g.edges.getEdge(i)); } g.getLayoutSize().transpose(); g.getDefaultPadding().transpose(); if (g instanceof CompoundDirectedGraph) { CompoundDirectedGraph cg = (CompoundDirectedGraph) g; for (int i = 0; i < cg.subgraphs.size(); i++) { transpose(cg.subgraphs.getNode(i)); } } } private static void transpose(Node n) { int temp = n.x; n.x = n.y; n.y = temp; temp = n.width; n.width = n.height; n.height = temp; if (n.getPadding() != null) { n.getPadding().transpose(); } if (n instanceof ConstantSizeNode) { for (Iterator<BorderNode> itr = ((ConstantSizeNode)n).borderNodes.iterator(); itr.hasNext();) { transpose(itr.next()); } } } private static void transpose(Edge e) { e.start.transpose(); e.end.transpose(); e.getPoints().transpose(); if (e.vNodes != null) { for (int i = 0; i < e.vNodes.size(); i++) { transpose(e.vNodes.getNode(i)); } } } static void storeNodesSizes(DirectedGraph g) { for (int i = 0; i < g.nodes.size(); i++) { Node n = g.nodes.getNode(i); if (n instanceof ConstantSizeNode) { ConstantSizeNode cn = (ConstantSizeNode) n; cn.constantWidth = cn.width; cn.constantHeight = cn.height; } } } static void recallNodesSizes(DirectedGraph g) { for (int i = 0; i < g.nodes.size(); i++) { Node n = g.nodes.getNode(i); if (n instanceof ConstantSizeNode) { ConstantSizeNode cn = (ConstantSizeNode) n; cn.width = cn.constantWidth; cn.height = cn.constantHeight; } } } static int getRankHeightFromNode(Node n, DirectedGraph g) { int rankHeight = -1; Rank rank = getNodeRank(n, g); if (rank != null) { for (int i = 0; i < rank.size(); i++) { rankHeight = Math.max(rankHeight, rank.getNode(i).height); } } return rankHeight; } static Rank getNodeRank(Node n, DirectedGraph g) { for (int i = 0; i < g.ranks.size(); i++) { Rank rank = g.ranks.getRank(i); if (!rank.isEmpty()) { if (n.y == rank.getNode(0).y) { return rank; } } } return null; } static int getOutogingEdgeBendpointX(Edge e, DirectedGraph g) { if ( e instanceof JointEdges) { return getOutogingEdgeBendpointX(((JointEdges)e).getLeadingEdge(), g); } else { if (e.vNodes == null) { if (e.end != null) { return e.end.x; } else { int sourceX = e.source.x + e.source.getOffsetOutgoing(); if (e.target instanceof ConstantSizeNode && ((ConstantSizeNode)e.target).getMinIncomingPadding() > 0 && e.target.x < sourceX && sourceX < e.target.x + e.target.width) { return sourceX; } else { return e.target.x + e.target.getOffsetIncoming(); } } } else { Node vn = e.vNodes.getNode(0); if (e instanceof ConstrainedEdge && ((ConstrainedEdge)e).getStyle().equals(ConstrainedEdge.ORTHOGONAL_ROUTING_STYLE)) { return vn.x + vn.getOffsetIncoming(); } int leftX = Integer.MIN_VALUE; int rightX = Integer.MAX_VALUE; for (int i = e.vNodes.size() - 1; i >= 0; i--) { vn = e.vNodes.getNode(i); int currentLeftX = getLeftX(vn, e, g); int currentRightX = getRightX(vn, e, g); if (currentLeftX > rightX) { return rightX; } else if (currentRightX < leftX) { return leftX; } else { if (currentLeftX > leftX) { leftX = currentLeftX; } if (currentRightX < rightX) { rightX = currentRightX; } } } int targetX = e.end != null ? e.end.x : e.target.x + e.target.getOffsetIncoming(); if (targetX > rightX) { return rightX; } else if (targetX < leftX) { return leftX; } return targetX; } } } static int getIncomingEdgeBendpointX(Edge e, DirectedGraph g) { if (e instanceof JointEdges) { return getIncomingEdgeBendpointX(((JointEdges)e).getLeadingEdge(), g); } else { if (e.vNodes == null) { if (e.start != null) { return e.start.x; } else { int targetX = e.target.x + e.target.getOffsetIncoming(); if (e.source instanceof ConstantSizeNode && ((ConstantSizeNode)e.source).getMinOutgoingPadding() > 0 && e.source.x < targetX && targetX < e.source.x + e.source.width) { return targetX; } else { return e.source.x + e.source.getOffsetOutgoing(); } } } else { Node vn = e.vNodes.getNode(e.vNodes.size() - 1); if (e instanceof ConstrainedEdge && ((ConstrainedEdge)e).getStyle().equals(ConstrainedEdge.ORTHOGONAL_ROUTING_STYLE)) { return vn.x + vn.getOffsetOutgoing(); } int leftX = Integer.MIN_VALUE; int rightX = Integer.MAX_VALUE; for (int i = e.vNodes.size() - 1; i >= 0; i--) { vn = e.vNodes.getNode(i); int currentLeftX = getLeftX(vn, e, g); int currentRightX = getRightX(vn, e, g); if (currentLeftX > rightX) { return rightX; } else if (currentRightX < leftX) { return leftX; } else { if (currentLeftX > leftX) { leftX = currentLeftX; } if (currentRightX < rightX) { rightX = currentRightX; } } } int sourceX = e.start != null ? e.start.x : e.source.x + e.source.getOffsetOutgoing(); if (sourceX > rightX) { return rightX; } else if (sourceX < leftX) { return leftX; } return sourceX; } } } private static int getLeftX(Node vn, Edge e, DirectedGraph g) { return vn.getLeft() != null ? vn.getLeft().x + vn.getLeft().width + g.getPadding(vn.getLeft()).right + e.getPadding() - 1 : 0; } private static int getRightX(Node vn, Edge e, DirectedGraph g) { return vn.getRight() != null ? vn.getRight().x - g.getPadding(vn.getRight()).left - e.getPadding() + 1 : g.getLayoutSize().width; } static void translateGraph(DirectedGraph g, int x, int y) { for (int i = 0; i < g.nodes.size(); i++) { translateNode(g.nodes.getNode(i), x, y); } for (int i = 0; i < g.edges.size(); i++) { translateEdge(g.edges.getEdge(i), x, y); } } static void translateNode(Node n, int x, int y) { n.x += x; n.y += y; if (n instanceof ConstantSizeNode) { ConstantSizeNode cn = (ConstantSizeNode) n; for (Iterator<BorderNode> itr = cn.borderNodes.iterator(); itr.hasNext();) { translateNode(itr.next(), x, y); } } } static void translateEdge(Edge e, int x, int y) { e.start.translate(x, y); e.end.translate(x, y); e.getPoints().translate(x, y); } static void invertEdges(DirectedGraph g) { for (int i = 0; i < g.edges.size(); i++) { Edge e = g.edges.getEdge(i); if (e.isFeedback()) { e.invert(); } } } }