+ // find the 'free' space, and how many children will be using it
+ for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+ std::list<Widget*>::iterator next = it; ++next;
+ free -= (*it)->minSize().height();
+ if (free < 0) free = 0;
+ if ((*it)->maxSize().height() - (*it)->minSize().height() <= 0)
+ adjustable.erase(it);
+ it = next;
+ }
+ // some widgets may have max heights that restrict them, find the 'true'
+ // amount of free space after these widgets are not included
+ if (!adjustable.empty()) {
+ do {
+ each = free / adjustable.size();
+ for (it = adjustable.begin(), end = adjustable.end(); it != end;) {
+ std::list<Widget*>::iterator next = it; ++next;
+ int m = (*it)->maxSize().height() - (*it)->minSize().height();
+ if (m > 0 && m < each) {
+ free -= m;
+ if (free < 0) free = 0;
+ adjustable.erase(it);
+ break; // if one is found to be fixed, then the free space needs to
+ // change, and the rest need to be reexamined
+ }
+ it = next;
+ }
+ } while (it != end && !adjustable.empty());
+ }
+
+ // place/size the widgets
+ if (!adjustable.empty())
+ each = free / adjustable.size();
+ else
+ each = 0;
+ for (it = visible.begin(), end = visible.end(); it != end; ++it) {
+ int h;
+ // is the widget adjustable?
+ std::list<Widget*>::const_iterator
+ found = std::find(adjustable.begin(), adjustable.end(), *it);
+ if (found != adjustable.end()) {
+ // adjustable
+ h = (*it)->minSize().height() + each;
+ } else {
+ // fixed
+ h = (*it)->minSize().height();
+ }
+ // align it horizontally
+ int xx = x;
+ int ww = std::max(std::min(w, (*it)->_max_size.width()),
+ (*it)->_min_size.width());
+ if (ww < w) {
+ switch(_alignment) {
+ case RenderStyle::RightBottomJustify:
+ xx += w - ww;
+ break;
+ case RenderStyle::CenterJustify:
+ xx += (w - ww) / 2;
+ break;
+ case RenderStyle::LeftTopJustify:
+ break;
+ }
+ }
+ (*it)->internal_moveresize(xx, y, ww, h);
+ (*it)->render();
+ (*it)->layout();
+ y += h + _bevel;
+ }