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:
@@ -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;
|
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
|
* Lays out all of the children of this chain and then requests that
|
||||||
* the supplied layout manager arrange those children and compute the
|
* the supplied layout manager arrange those children and compute the
|
||||||
* dimensions of this chain based on all of that information.
|
* 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
|
// first layout our children
|
||||||
for (int i = 0; i < _children.size(); i++) {
|
for (int i = 0; i < _children.size(); i++) {
|
||||||
@@ -175,6 +209,86 @@ public class Chain implements Element
|
|||||||
cviz.layoutChain(this, gfx);
|
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
|
* Adds a child to this chain. The specified class is assumed to
|
||||||
* directly inherit from the class that is the root of this chain.
|
* 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;
|
package com.samskivert.viztool.viz;
|
||||||
|
|
||||||
@@ -83,13 +83,6 @@ public class ChainGroup
|
|||||||
public ChainGroup layout (
|
public ChainGroup layout (
|
||||||
Graphics2D gfx, double pageWidth, double pageHeight)
|
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
|
// we'll need room to incorporate our title
|
||||||
TextLayout layout = new TextLayout(_pkg, FontPicker.getTitleFont(),
|
TextLayout layout = new TextLayout(_pkg, FontPicker.getTitleFont(),
|
||||||
gfx.getFontRenderContext());
|
gfx.getFontRenderContext());
|
||||||
@@ -103,6 +96,18 @@ public class ChainGroup
|
|||||||
pageWidth -= 2*BORDER;
|
pageWidth -= 2*BORDER;
|
||||||
pageHeight -= (2*BORDER + titleAscent);
|
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
|
// arrange them on the page
|
||||||
ElementLayout elay = new PackedColumnElementLayout();
|
ElementLayout elay = new PackedColumnElementLayout();
|
||||||
ArrayList overflow = new ArrayList();
|
ArrayList overflow = new ArrayList();
|
||||||
|
|||||||
Reference in New Issue
Block a user