List<UIComponent> comps = Lists.newArrayList();
List<UIComponent> compsBack = Lists.newArrayList();
for (int i = 0; i < content.size(); i++) {
final Spatial spat = content.get(i);
if (spat instanceof UIComponent) {
final UIComponent comp = (UIComponent) spat;
final Rectangle2 rect = comp.getRelativeComponentBounds(storeA);
final Rectangle2 minRect = comp.getRelativeMinComponentBounds(storeB);
if (_horizontal) {
comp.fitComponentIn(minRect.getWidth(), rect.getHeight());
} else {
comp.fitComponentIn(rect.getWidth(), minRect.getHeight());
}
comps.add(comp);
}
}
// if we have components to layout...
if (!comps.isEmpty()) {
// Determine how much space we feel we need.
final int reqSpace = _horizontal ? getSumOfAllWidths(content) : getSumOfAllHeights(content);
// How much extra space do we have?
int freeSpace = (_horizontal ? container.getContentWidth() : container.getContentHeight()) - reqSpace;
int relaxIndex = 0;
// cycle through until we've given away all of the space
while ((freeSpace > 0 || relaxIndex == 0) && !comps.isEmpty() && relaxIndex < RowLayout.MAX_RELAX) {
final int extraPerComp = freeSpace / comps.size();
while (!comps.isEmpty()) {
final UIComponent comp = comps.remove(0);
Rectangle2 rect = comp.getRelativeComponentBounds(storeA);
final Rectangle2 origRect = storeB.set(rect);
if (freeSpace < 0) {
freeSpace = 0;
}
if (_horizontal) {
final int height = _expandsVertically ? container.getContentHeight() : rect.getHeight();
final int width = (_expandsHorizontally ? extraPerComp : 0) + rect.getWidth();
if (height == rect.getHeight() && width == rect.getWidth()) {
continue;
}
comp.fitComponentIn(width, height);
rect = comp.getRelativeComponentBounds(storeA);
if (Math.abs(rect.getWidth() - width) <= 1) {
compsBack.add(comp);
}
freeSpace -= rect.getWidth() - origRect.getWidth();
} else {
final int width = _expandsHorizontally ? container.getContentWidth() : rect.getWidth();
final int height = (_expandsVertically ? extraPerComp : 0) + rect.getHeight();
if (height == rect.getHeight() && width == rect.getWidth()) {
continue;
}
comp.fitComponentIn(width, height);
rect = comp.getRelativeComponentBounds(storeA);
if (Math.abs(rect.getHeight() - height) <= 1) {
compsBack.add(comp);
}
freeSpace -= rect.getHeight() - origRect.getHeight();
}
}
final List<UIComponent> compsTemp = comps;
comps = compsBack;
compsBack = compsTemp;
relaxIndex++;
}
int x = 0;
int y = !_expandsVertically && !_horizontal ? container.getContentHeight() - reqSpace : 0;
// Now, go through children and set proper location.
for (int i = 0; i < content.size(); i++) {
final Spatial spat = _horizontal ? content.get(i) : content.get(content.size() - i - 1);
if (!(spat instanceof UIComponent)) {
continue;
}
final UIComponent comp = (UIComponent) spat;
final Rectangle2 rect = comp.getRelativeComponentBounds(storeA);
if (_horizontal) {
comp.setLocalXY(x - rect.getX(), Math.max(container.getContentHeight() / 2 - rect.getHeight() / 2
- rect.getY(), 0));
x += rect.getWidth();
} else {
comp.setLocalXY(Math.max(container.getContentWidth() / 2 - rect.getWidth() / 2 - rect.getX(), 0), y
- rect.getY());
y += rect.getHeight();
}
}
}