| /******************************************************************************* |
| * 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); |
| } |
| } |
| |
| } |