- OtkWidget *prev_widget = 0;
-
- for (it = _children.begin(); it != end; ++it) {
- tmp = *it;
- int x, y;
-
- if (prev_widget)
- y = prev_widget->_rect.y() + prev_widget->_rect.height() + _bevel_width;
- else
- y = _rect.y() + _bevel_width;
- x = (widest - tmp->_rect.width()) / 2 + _bevel_width;
-
- tmp->move(x, y);
-
- prev_widget = tmp;
+ if (visible.empty()) return;
+
+ if ((unsigned)(_borderwidth * 2 + _bevel * 2) > _area.width() ||
+ (unsigned)(_borderwidth * 2 + _bevel * 2) > _area.height())
+ return; // not worth laying anything out!
+
+ int x, y; unsigned int w, h; // working area
+ x = y = _bevel;
+ w = _area.width() - _borderwidth * 2 - _bevel * 2;
+ h = _area.height() - _borderwidth * 2 - _bevel * 2;
+
+ int free = h - (visible.size() - 1) * _bevel;
+ if (free < 0) free = 0;
+ unsigned int each;
+
+ std::list<Widget*> adjustable = visible;
+
+ // 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;
+ unsigned 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());