if (det instanceof CircuitDetermination.Input) {
CircuitDetermination.Input input = (CircuitDetermination.Input) det;
return new Layout(input.getName());
} else if (det instanceof CircuitDetermination.Value) {
CircuitDetermination.Value value = (CircuitDetermination.Value) det;
ComponentFactory factory = Constant.FACTORY;
AttributeSet attrs = factory.createAttributeSet();
attrs.setValue(Constant.ATTR_VALUE,
Integer.valueOf(value.getValue()));
Bounds bds = factory.getOffsetBounds(attrs);
return new Layout(bds.getWidth(), bds.getHeight(),
-bds.getY(), factory, attrs,
new Layout[0], 0);
}
// We know det is a Gate. Determine sublayouts.
CircuitDetermination.Gate gate = (CircuitDetermination.Gate) det;
ComponentFactory factory = gate.getFactory();
ArrayList<CircuitDetermination> inputs = gate.getInputs();
// Handle a NOT implemented with a NAND as a special case
if (gate.isNandNot()) {
CircuitDetermination subDet = inputs.get(0);
if (!(subDet instanceof CircuitDetermination.Input)) {
Layout[] sub = new Layout[1];
sub[0] = layoutGatesSub(subDet);
sub[0].y = 0;
AttributeSet attrs = factory.createAttributeSet();
attrs.setValue(GateAttributes.ATTR_SIZE, GateAttributes.SIZE_NARROW);
attrs.setValue(GateAttributes.ATTR_INPUTS, Integer.valueOf(2));
// determine layout's width
Bounds bds = factory.getOffsetBounds(attrs);
int betweenWidth = 40;
if (sub[0].width == 0) {
betweenWidth = 0;
}
int width = sub[0].width + betweenWidth + bds.getWidth();
// determine outputY and layout's height.
int outputY = sub[0].y + sub[0].outputY;
int height = sub[0].height;
int minOutputY = roundUp(-bds.getY());
if (minOutputY > outputY) {
// we have to shift everything down because otherwise
// the component will peek over the rectangle's top.
int dy = minOutputY - outputY;
sub[0].y += dy;
height += dy;
outputY += dy;
}
int minHeight = outputY + bds.getY() + bds.getHeight();
if (minHeight > height) {
height = minHeight;
}
// ok; create and return the layout.
return new Layout(width, height, outputY, factory, attrs,
sub, sub[0].width);
}
}
Layout[] sub = new Layout[inputs.size()];
// maximum width of sublayouts
int subWidth = 0;
// total height of sublayouts
int subHeight = 0;
for (int i = 0; i < sub.length; i++) {
sub[i] = layoutGatesSub(inputs.get(i));
if (sub.length % 2 == 0 && i == (sub.length + 1) / 2
&& sub[i - 1].height + sub[i].height == 0) {
// if there are an even number of inputs, then there is a
// 20-tall gap between the middle two inputs. Ensure the two
// middle inputs are at least 20 pixels apart.
subHeight += 10;
}
sub[i].y = subHeight;
subWidth = Math.max(subWidth, sub[i].width);
subHeight += sub[i].height + 10;
}
subHeight -= 10;
AttributeSet attrs = factory.createAttributeSet();
if (factory == NotGate.FACTORY) {
attrs.setValue(NotGate.ATTR_SIZE, NotGate.SIZE_NARROW);
} else {
attrs.setValue(GateAttributes.ATTR_SIZE, GateAttributes.SIZE_NARROW);
int ins = sub.length;
attrs.setValue(GateAttributes.ATTR_INPUTS, Integer.valueOf(ins));
}
// determine layout's width
Bounds bds = factory.getOffsetBounds(attrs);
int betweenWidth = 40 + 10 * (sub.length / 2 - 1);
if (sub.length == 1) {
betweenWidth = 20;
}