Added support for breaking chains apart when they are too big to fit on a

page.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@206 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2001-07-24 20:07:33 +00:00
parent e78b957839
commit 2ba1cd0401
2 changed files with 129 additions and 10 deletions
@@ -1,5 +1,5 @@
//
// $Id: Chain.java,v 1.5 2001/07/17 07:18:09 mdb Exp $
// $Id: Chain.java,v 1.6 2001/07/24 20:07:33 mdb Exp $
package com.samskivert.viztool.viz;
@@ -162,8 +162,42 @@ public class Chain implements Element
* Lays out all of the children of this chain and then requests that
* the supplied layout manager arrange those children and compute the
* dimensions of this chain based on all of that information.
*
* @param gfx the graphics context to use when computing dimensions.
* @param cviz the chain visualizer to be used for laying out.
* @param width the width in which the chain must fit.
* @param height the height in which the chain must fit.
*
* @return if the chain cannot be laid out in the required dimensions,
* branches of the chain will be removed so that it can fit into the
* necessary dimensions. A new chain will be created with the
* remaining branches which should be laid out itself so that it too
* may further prune itself to fit into the necessary dimensions. If
* the chain fits into the requested dimensions, null will be
* returned.
*/
public void layout (Graphics2D gfx, ChainVisualizer cviz)
public Chain layout (Graphics2D gfx, ChainVisualizer cviz,
double width, double height)
{
// lay everything out
layout(gfx, cviz);
// determine if we need to do some pruning (we only deal with
// height pruning presently)
if (_bounds.getHeight() <= height) {
return null;
}
double x = 0, y = 0;
Chain oflow = pruneOverflow(x, y, width, height);
// if something wigged out and we try to overflow our whole selves
// at this point (like this chain is one big fat chain with no
// children that doesn't fit into the space) we must punt and
// pretend like there's no overflow
return (oflow == this) ? null : oflow;
}
protected void layout (Graphics2D gfx, ChainVisualizer cviz)
{
// first layout our children
for (int i = 0; i < _children.size(); i++) {
@@ -175,6 +209,86 @@ public class Chain implements Element
cviz.layoutChain(this, gfx);
}
protected Chain pruneOverflow (
double x, double y, double width, double height)
{
// offset our current position by the position of this chain
Rectangle2D bounds = getBounds();
x += bounds.getX();
y += bounds.getY();
Chain oflow = null;
for (int i = 0; i < _children.size(); i++) {
Chain child = (Chain)_children.get(i);
// if we've switched to flowing over, just add this chain to
// the overflow chain (and remove it from ourselves)
if (oflow != null) {
_children.remove(i--);
oflow._children.add(child);
continue;
}
Rectangle2D cbounds = child.getBounds();
double cx = cbounds.getX(), cy = cbounds.getY();
// if this child doesn't fit in the current space, we need to
// break it up and overflow the extra nodes
if (y + cy + cbounds.getHeight() > height) {
Chain coflow = child.pruneOverflow(x, y, width, height);
// make sure this child claims some sort of overflow (if
// it doesn't something is wacked, but we'll try to deal)
if (coflow != null) {
// if this entire child is overflowed
if (coflow == child) {
// remove the child from this chain and add it to our
// overflow chain
_children.remove(i--);
}
// regardless, add what we got to the overflow chain
oflow = createOverflowChain();
oflow._children.add(coflow);
} else {
System.err.println("Overflowing child unable " +
"to overflow " + child._name + ".");
}
}
}
// if we have no children (or we overflowed *all* of our children)
// then we need to overflow ourselves rather than create a new
// chain for overflowing
if (_children.size() == 0) {
// grab our kids back from the overflow chain
if (oflow != null) {
_children = oflow._children;
}
return this;
} else {
// otherwise, adjust our height to just enclose the height of
// our last child because we removed some children and changed
// our dimensions. this is sort of a hack because it assumes
// that the chain visualizer isn't leaving any gap beyond the
// bottom of a child chain but it's somewhat safe because if
// they did, that gap would accumulate unaesthetically
Chain child = (Chain)_children.get(_children.size()-1);
Rectangle2D cbounds = child.getBounds();
_bounds.setRect(_bounds.getX(), _bounds.getY(), _bounds.getWidth(),
cbounds.getY() + cbounds.getHeight());
}
return oflow;
}
protected Chain createOverflowChain ()
{
return new Chain(_name, _root, _inpkg);
}
/**
* Adds a child to this chain. The specified class is assumed to
* directly inherit from the class that is the root of this chain.
@@ -1,5 +1,5 @@
//
// $Id: ChainGroup.java,v 1.7 2001/07/24 18:07:35 mdb Exp $
// $Id: ChainGroup.java,v 1.8 2001/07/24 20:07:33 mdb Exp $
package com.samskivert.viztool.viz;
@@ -83,13 +83,6 @@ public class ChainGroup
public ChainGroup layout (
Graphics2D gfx, double pageWidth, double pageHeight)
{
// lay out the internal structure of our chains
ChainVisualizer clay = new CascadingChainVisualizer();
for (int i = 0; i < _roots.size(); i++) {
Chain chain = (Chain)_roots.get(i);
chain.layout(gfx, clay);
}
// we'll need room to incorporate our title
TextLayout layout = new TextLayout(_pkg, FontPicker.getTitleFont(),
gfx.getFontRenderContext());
@@ -103,6 +96,18 @@ public class ChainGroup
pageWidth -= 2*BORDER;
pageHeight -= (2*BORDER + titleAscent);
// lay out the internal structure of our chains
ChainVisualizer clay = new CascadingChainVisualizer();
for (int i = 0; i < _roots.size(); i++) {
Chain chain = (Chain)_roots.get(i);
Chain oflow = chain.layout(gfx, clay, pageWidth, pageHeight);
// if this chain overflowed when being laid out, add the newly
// created root to our list
if (oflow != null) {
_roots.add(i+1, oflow);
}
}
// arrange them on the page
ElementLayout elay = new PackedColumnElementLayout();
ArrayList overflow = new ArrayList();