in src/main/java/org/jetbrains/plugins/spotbugs/gui/common/MultiSplitLayout.java [615:704]
private void layout1(final Node root, final Rectangle bounds) {
if (root instanceof Leaf) {
root.setBounds(bounds);
} else if (root instanceof Split) {
final Split split = (Split) root;
final Iterator<Node> splitChildren = split.getChildren().iterator();
Rectangle childBounds;
final int dividerSize = getDividerSize();
/* Layout the Split's child Nodes' along the X axis. The bounds
* of each child will have the same y coordinate and height as the
* layout1() bounds argument.
*
* Note: the column layout code - that's the "else" clause below
* this if, is identical to the X axis (rowLayout) code below.
*/
if (split.isRowLayout()) {
double x = bounds.getX();
while (splitChildren.hasNext()) {
final Node splitChild = splitChildren.next();
final Divider dividerChild = splitChildren.hasNext() ? (Divider) splitChildren.next() : null;
final double childWidth;
if (getFloatingDividers()) {
childWidth = preferredNodeSize(splitChild).getWidth();
} else {
if (dividerChild != null) {
childWidth = dividerChild.getBounds().getX() - x;
} else {
childWidth = split.getBounds().getMaxX() - x;
}
}
childBounds = boundsWithXandWidth(bounds, x, childWidth);
layout1(splitChild, childBounds);
if (getFloatingDividers() && dividerChild != null) {
final double dividerX = childBounds.getMaxX();
final Rectangle dividerBounds = boundsWithXandWidth(bounds, dividerX, dividerSize);
dividerChild.setBounds(dividerBounds);
}
if (dividerChild != null) {
x = dividerChild.getBounds().getMaxX();
}
}
}
/* Layout the Split's child Nodes' along the Y axis. The bounds
* of each child will have the same x coordinate and width as the
* layout1() bounds argument. The algorithm is identical to what's
* explained above, for the X axis case.
*/
else {
double y = bounds.getY();
while (splitChildren.hasNext()) {
final Node splitChild = splitChildren.next();
final Divider dividerChild = splitChildren.hasNext() ? (Divider) splitChildren.next() : null;
final double childHeight;
if (getFloatingDividers()) {
childHeight = preferredNodeSize(splitChild).getHeight();
} else {
if (dividerChild != null) {
childHeight = dividerChild.getBounds().getY() - y;
} else {
childHeight = split.getBounds().getMaxY() - y;
}
}
childBounds = boundsWithYandHeight(bounds, y, childHeight);
layout1(splitChild, childBounds);
if (getFloatingDividers() && dividerChild != null) {
final double dividerY = childBounds.getMaxY();
final Rectangle dividerBounds = boundsWithYandHeight(bounds, dividerY, dividerSize);
dividerChild.setBounds(dividerBounds);
}
if (dividerChild != null) {
y = dividerChild.getBounds().getMaxY();
}
}
}
/* The bounds of the Split node root are set to be just
* big enough to contain all of its children, but only
* along the axis it's allocating space on. That's
* X for rows, Y for columns. The second pass of the
* layout algorithm - see layoutShrink()/layoutGrow()
* allocates extra space.
*/
minimizeSplitBounds(split, bounds);
}
}