blob: 33cdfe19c7ae1892c55a466bb2d475633eb57368 [file] [log] [blame]
/******************************************************************************
* 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();
}
}
}
}