blob: ed3f7353d7cf2b2f43955bca0adc935a8aa6879b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2005 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.draw2d.graph;
import java.util.HashSet;
import java.util.Set;
/**
* Calculates the X-coordinates for nodes in a compound directed graph.
* @author Randy Hudson
* @since 2.1.2
*/
class CompoundHorizontalPlacement extends HorizontalPlacement {
class LeftRight {
//$TODO Delete and use NodePair class, equivalent
Object left, right;
LeftRight(Object l, Object r) {
left = l; right = r;
}
public boolean equals(Object obj) {
LeftRight entry = (LeftRight)obj;
return entry.left.equals(left) && entry.right.equals(right);
}
public int hashCode() {
return left.hashCode() ^ right.hashCode();
}
}
Set entries = new HashSet();
/**
* @see org.eclipse.graph.HorizontalPlacement#applyGPrime()
*/
void applyGPrime() {
super.applyGPrime();
NodeList subgraphs = ((CompoundDirectedGraph)graph).subgraphs;
for (int i = 0; i < subgraphs.size(); i++) {
Subgraph s = (Subgraph)subgraphs.get(i);
s.x = s.left.x;
s.width = s.right.x + s.right.width - s.x;
}
}
/**
* @see HorizontalPlacement#buildRankSeparators(RankList)
*/
void buildRankSeparators(RankList ranks) {
CompoundDirectedGraph g = (CompoundDirectedGraph)graph;
Rank rank;
for (int row = 0; row < g.ranks.size(); row++) {
rank = g.ranks.getRank(row);
Node n = null, prev = null;
for (int j = 0; j < rank.size(); j++) {
n = rank.getNode(j);
if (prev == null) {
Node left = addSeparatorsLeft(n, null);
if (left != null) {
Edge e = new Edge(graphLeft, getPrime(left), 0, 0);
prime.edges.add(e);
e.delta = graph.getPadding(n).left + graph.getMargin().left;
}
} else {
Subgraph s = GraphUtilities.getCommonAncestor(prev, n);
Node left = addSeparatorsRight(prev, s);
Node right = addSeparatorsLeft(n, s);
createEdge(left, right);
}
prev = n;
}
if (n != null)
addSeparatorsRight(n, null);
}
}
void createEdge(Node left, Node right) {
LeftRight entry = new LeftRight(left, right);
if (entries.contains(entry))
return;
entries.add(entry);
int separation = left.width + Math.max(
graph.getPadding(left).right,
graph.getPadding(right).left);
prime.edges.add(new Edge(
getPrime(left), getPrime(right), separation, 0
));
}
Node addSeparatorsLeft(Node n, Subgraph graph) {
Subgraph parent = n.getParent();
while (parent != graph && parent != null) {
createEdge(getLeft(parent), n);
n = parent.left;
parent = parent.getParent();
}
return n;
}
Node addSeparatorsRight(Node n, Subgraph graph) {
Subgraph parent = n.getParent();
while (parent != graph && parent != null) {
createEdge(n, getRight(parent));
n = parent.right;
parent = parent.getParent();
}
return n;
}
Node getLeft(Subgraph s) {
if (s.left == null) {
s.left = new SubgraphBoundary(s, graph.getPadding(s), 1);
s.left.rank = (s.head.rank + s.tail.rank) / 2;
Node head = getPrime(s.head);
Node tail = getPrime(s.tail);
Node left = getPrime(s.left);
Node right = getPrime(getRight(s));
prime.edges.add(new Edge(left, right, s.width, 0));
prime.edges.add(new Edge(left, head, 0, 1));
prime.edges.add(new Edge(head, right, 0, 1));
prime.edges.add(new Edge(left, tail, 0, 1));
prime.edges.add(new Edge(tail, right, 0, 1));
}
return s.left;
}
Node getRight(Subgraph s) {
if (s.right == null) {
s.right = new SubgraphBoundary(s, graph.getPadding(s), 3);
s.right.rank = (s.head.rank + s.tail.rank) / 2;
}
return s.right;
}
Node getPrime(Node n) {
Node nPrime = get(n);
if (nPrime == null) {
nPrime = new Node(n);
prime.nodes.add(nPrime);
map(n, nPrime);
}
return nPrime;
}
public void visit(DirectedGraph g) {
super.visit(g);
}
}