blob: 0a7dbd115e2726582ce05254bc62305c49e791c6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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.examples.tree;
import java.util.List;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.geometry.Transposer;
/**
* @author hudsonr
* Created on Apr 22, 2003
*/
class NormalLayout extends BranchLayout {
NormalLayout(TreeBranch branch) {
super(branch);
}
/**
* @see org.eclipse.draw2d.examples.tree.BranchLayout#calculateDepth()
*/
void calculateDepth() {
depth = 0;
List subtrees = getSubtrees();
for (int i = 0; i < subtrees.size(); i++)
depth = Math.max(depth, ((TreeBranch)subtrees.get(i)).getDepth());
depth++;
}
protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
Rectangle union = branch.getNodeBounds().getCopy();
// if (branch.isExpanded())
union.union(branch.getContentsPane().getBounds());
return union.getSize();
}
public void layout(IFigure f) {
Animation.recordInitialState(f);
if (Animation.playbackState(f))
return;
Transposer transposer = getTransposer();
IFigure contents = branch.getContentsPane();
IFigure node = branch.getNode();
contents.validate();
Rectangle branchBounds = transposer.t(branch.getBounds());
Point topLeft = branchBounds.getTopLeft();
Rectangle nodeLocation = new Rectangle(topLeft, transposer.t(node.getPreferredSize()));
nodeLocation.height = rowHeight - getMajorSpacing();
if (!contents.isVisible() || contents.getChildren().isEmpty()) {
nodeLocation.x += (branchBounds.width - nodeLocation.width)/2;
node.setBounds(transposer.t(nodeLocation));
contents.setBounds(
transposer.t(nodeLocation.getTranslated(0, rowHeight).setSize(0, 0)));
return;
}
Rectangle contentsLocation =
new Rectangle(topLeft, transposer.t(contents.getPreferredSize()));
contents.setSize(contents.getPreferredSize());
contentsLocation.y += rowHeight;
TreeBranch firstChild = (TreeBranch)contents.getChildren().get(0);
TreeBranch lastChild =
(TreeBranch)contents.getChildren().get(contents.getChildren().size() - 1);
int leftInset =
firstChild.getContourLeft()[0]
+ transposer.t(firstChild.getBounds()).x
- transposer.t(contents.getBounds()).x;
int rightInset =
lastChild.getContourRight()[0]
- transposer.t(lastChild.getBounds()).right()
+ transposer.t(contents.getBounds()).right();
rightInset = Math.max(rightInset, 0);
leftInset = Math.max(leftInset, 0);
int childrenSpan = contentsLocation.width - leftInset - rightInset;
switch (branch.getAlignment()) {
case PositionConstants.CENTER :
leftInset += (childrenSpan - nodeLocation.width) / 2;
}
if (leftInset > 0)
nodeLocation.x += leftInset;
else
contentsLocation.x -= leftInset;
int adjust =
branchBounds.width
- Rectangle.SINGLETON.setBounds(contentsLocation).union(nodeLocation).width;
adjust /= 2;
nodeLocation.x += adjust;
contentsLocation.x += adjust;
node.setBounds(transposer.t(nodeLocation));
// Animation.setBounds(node, transposer.t(nodeLocation));
// Animation.setBounds(contents, transposer.t(contentsLocation));
contents.setBounds(transposer.t(contentsLocation));
}
void mergeContour(int[] destination, int[] source, int startdepth, int offset) {
for (int i = startdepth; i<source.length; i++)
destination[i+1] = source[i] + offset;
}
/**
* @see org.eclipse.draw2d.examples.tree.BranchLayout#paintLines(org.eclipse.draw2d.Graphics)
*/
void paintLines(Graphics g) {
if (getTransposer().isEnabled()) {
IFigure node = branch.getNode();
int left = node.getBounds().right();
int right = branch.getContentsPane().getBounds().x - 1;
int yMid = node.getBounds().getCenter().y;
int xMid = (left + right) / 2;
List children = getSubtrees();
if (children.size() == 0)
return;
g.drawLine(left, yMid, xMid, yMid);
int yMin = yMid;
int yMax = yMid;
for (int i=0; i<children.size(); i++){
int y = ((TreeBranch)children.get(i)).getNodeBounds().getCenter().y;
g.drawLine(xMid, y, right, y);
yMin = Math.min(yMin, y);
yMax = Math.max(yMax, y);
}
g.drawLine(xMid, yMin, xMid, yMax);
} else {
IFigure node = branch.getNode();
int xMid = node.getBounds().getCenter().x;
int top = node.getBounds().bottom();
int bottom = branch.getContentsPane().getBounds().y - 1;
int yMid = (top + bottom) / 2;
List children = getSubtrees();
if (children.size() == 0)
return;
g.drawLine(xMid, top, xMid, yMid);
int xMin = xMid;
int xMax = xMid;
for (int i=0; i<children.size(); i++){
int x = ((TreeBranch)children.get(i)).getNodeBounds().getCenter().x;
g.drawLine(x, yMid, x, bottom);
xMin = Math.min(xMin, x);
xMax = Math.max(xMax, x);
}
g.drawLine(xMin, yMid, xMax, yMid);
}
}
/**
* @see org.eclipse.draw2d.examples.tree.BranchLayout#updateContours()
*/
void updateContours() {
Transposer transposer = getTransposer();
//Make sure we layout first
branch.validate();
cachedContourLeft = new int[getDepth()];
cachedContourRight = new int[getDepth()];
Rectangle clientArea =
transposer.t(branch.getNodeBounds().getUnion(branch.contents.getBounds()));
Rectangle nodeBounds = transposer.t(branch.getNodeBounds());
Rectangle contentsBounds = transposer.t(branch.getContentsPane().getBounds());
cachedContourLeft[0] = nodeBounds.x - clientArea.x;
cachedContourRight[0] = clientArea.right() - nodeBounds.right();
if (!branch.isExpanded())
return;
List subtrees = getSubtrees();
TreeBranch subtree;
int currentDepth = 0;
for (int i = 0; i < subtrees.size() && currentDepth < getDepth(); i++) {
subtree = (TreeBranch)subtrees.get(i);
if (subtree.getDepth() > currentDepth) {
int leftContour[] = subtree.getContourLeft();
int leftOffset = transposer.t(subtree.getBounds()).x - clientArea.x;
mergeContour(cachedContourLeft, leftContour, currentDepth, leftOffset);
currentDepth = subtree.getDepth();
}
}
currentDepth = 0;
for (int i = subtrees.size() - 1; i >= 0 && currentDepth < getDepth(); i--) {
subtree = (TreeBranch)subtrees.get(i);
if (subtree.getDepth() > currentDepth) {
int rightContour[] = subtree.getContourRight();
int rightOffset =
clientArea.right() - transposer.t(subtree.getBounds()).right();
mergeContour(cachedContourRight, rightContour, currentDepth, rightOffset);
currentDepth = subtree.getDepth();
}
}
}
/**
* @see org.eclipse.draw2d.examples.tree.BranchLayout#updateRowHeights()
*/
void updateRowHeights() {
Transposer transposer = getTransposer();
preferredRowHeights = new int[getDepth()];
preferredRowHeights[0] =
transposer.t(branch.getNode().getPreferredSize()).height + getMajorSpacing();
if (!branch.isExpanded())
return;
List subtrees = getSubtrees();
TreeBranch subtree;
for (int i = 0; i < subtrees.size(); i++) {
subtree = (TreeBranch)subtrees.get(i);
int rowHeights[] = subtree.getPreferredRowHeights();
for (int row = 0; row < rowHeights.length; row++)
preferredRowHeights[row + 1] =
Math.max(preferredRowHeights[row + 1], rowHeights[row]);
}
}
/**
* @see org.eclipse.draw2d.examples.tree.BranchLayout#setRowHeights(int[], int)
*/
void setRowHeights(int[] heights, int offset) {
super.setRowHeights(heights, offset);
if (branch.isExpanded()) {
List subtrees = getSubtrees();
offset++;
for (int i=0; i<subtrees.size(); i++)
((TreeBranch)subtrees.get(i)).setRowHeights(heights, offset);
}
}
}