package husacct.graphics.task.modulelayout;
import husacct.graphics.domain.figures.BaseFigure;
import husacct.graphics.domain.figures.RelationFigure;
import husacct.graphics.task.modulelayout.layered.LayoutStrategy;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.jhotdraw.draw.AbstractCompositeFigure;
import org.jhotdraw.draw.ConnectionFigure;
import org.jhotdraw.draw.Figure;
public class BasicLayoutStrategy implements LayoutStrategy {
private static final double VERT_SPACE_FIRST_LINE = 50.0;
private static final double VERT_ITEM_SPACING = 110.0;
private static final double HORZ_ITEM_SPACING = 110.0;
private AbstractCompositeFigure drawing = null;
public BasicLayoutStrategy(AbstractCompositeFigure theDrawing) {
drawing = theDrawing;
}
@Override
public void doLayout() {
double x = HORZ_ITEM_SPACING, y = VERT_SPACE_FIRST_LINE;
double maxHeightOnLine = 0.0;
int figuresOnLine = 0;
ArrayList<Figure> figures = new ArrayList<Figure>();
ArrayList<Figure> connectors = new ArrayList<Figure>();
figures.addAll(drawing.getChildren());
int itemsToPosition = countItemsToPosition(figures);
int maxFiguresOnRow = (int) Math.ceil(Math.sqrt(itemsToPosition));
for (Figure f : figures)
if (!isConnector(f) && !inContainer(f)) {
Rectangle2D.Double bounds = f.getBounds();
if (figuresOnLine >= maxFiguresOnRow) {
x = HORZ_ITEM_SPACING;
y += maxHeightOnLine + VERT_ITEM_SPACING;
figuresOnLine = 0;
maxHeightOnLine = 0;
}
bounds.x = x;
bounds.y = y;
Point2D.Double anchor = new Point2D.Double(bounds.x, bounds.y);
Point2D.Double lead = new Point2D.Double(bounds.x + bounds.width, bounds.y + bounds.height);
f.willChange();
f.setBounds(anchor, lead);
f.changed();
x += bounds.width + HORZ_ITEM_SPACING;
maxHeightOnLine = Math.max(maxHeightOnLine, bounds.height);
figuresOnLine++;
} else
connectors.add(f);
}
private int countItemsToPosition(List<Figure> figures) {
int count = 0;
for (Figure f : figures) {
BaseFigure bf = (BaseFigure) f;
if (!bf.isInContainer() && !bf.isLine()) count++;
}
return count;
}
private boolean inContainer(Figure f) {
BaseFigure bf = (BaseFigure) f;
return bf.isInContainer();
}
// NOTE: Patrick: I'm not quite sure if this code should be here. We really
// need to discuss this kind of
// code. It's ugly and unneccessary I think.
private boolean isConnector(Figure figure) {
return figure instanceof ConnectionFigure
|| figure instanceof BaseFigure
&& figure instanceof RelationFigure;
}
}