116
117
118
119
120
121
126 auto isNonEmptyBox = [](
QBoxLayoutItem *box) {
return box && box->item && !box->item->isEmpty();};
128 auto topIt = std::find_if(list.begin(), list.end(), isNonEmptyBox);
129 if (topIt != list.end()) {
132 auto bottomIt = std::find_if(list.rbegin(), std::make_reverse_iterator(--topIt), isNonEmptyBox);
133 *lastBox = *bottomIt;
141 Q_Q(
const QBoxLayout);
147 firstAndLastNonEmptyBox(list, &leftBox, &rightBox);
148 if (dir == QBoxLayout::RightToLeft)
149 qSwap(leftBox, rightBox);
154 QLayoutItem *itm = leftBox
->item;
155 if (QWidget *w = itm->widget())
156 leftDelta = itm->geometry().left() - w->geometry().left();
159 QLayoutItem *itm = rightBox
->item;
160 if (QWidget *w = itm->widget())
161 rightDelta = w->geometry().right() - itm->geometry().right();
163 QWidget *w = q->parentWidget();
164 Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QGuiApplication::layoutDirection();
165 if (layoutDirection == Qt::RightToLeft)
166 qSwap(leftDelta, rightDelta);
168 l = qMax(l, leftDelta);
169 r = qMax(r, rightDelta);
172 int count = top || bottom ? list.count() : 0;
173 for (
int i = 0; i < count; ++i) {
175 QLayoutItem *itm = box
->item;
176 QWidget *w = itm->widget();
178 QRect lir = itm->geometry();
179 QRect wr = w->geometry();
181 t = qMax(t, lir.top() - wr.top());
183 b = qMax(b, wr.bottom() - lir.bottom());
191 firstAndLastNonEmptyBox(list, &topBox, &bottomBox);
192 if (dir == QBoxLayout::BottomToTop) {
193 qSwap(topBox, bottomBox);
197 QLayoutItem *itm = topBox
->item;
198 QWidget *w = itm->widget();
200 t = qMax(t, itm->geometry().top() - w->geometry().top());
203 if (bottom && bottomBox) {
204 QLayoutItem *itm = bottomBox
->item;
205 QWidget *w = itm->widget();
207 b = qMax(b, w->geometry().bottom() - itm->geometry().bottom());
211 int count = left || right ? list.count() : 0;
212 for (
int i = 0; i < count; ++i) {
214 QLayoutItem *itm = box
->item;
215 QWidget *w = itm->widget();
217 QRect lir = itm->geometry();
218 QRect wr = w->geometry();
220 l = qMax(l, lir.left() - wr.left());
222 r = qMax(r, wr.right() - lir.right());
248 int maxw = horz(dir) ? 0 : QLAYOUTSIZE_MAX;
249 int maxh = horz(dir) ? QLAYOUTSIZE_MAX : 0;
264 QSizePolicy::ControlTypes controlTypes1;
265 QSizePolicy::ControlTypes controlTypes2;
266 int fixedSpacing = q->spacing();
267 int previousNonEmptyIndex = -1;
269 QStyle *style =
nullptr;
270 if (fixedSpacing < 0) {
271 if (QWidget *parentWidget = q->parentWidget())
272 style = parentWidget->style();
275 for (
int i = 0; i < n; i++) {
277 QSize max = box->item->maximumSize();
278 QSize min = box->item->minimumSize();
279 QSize hint = box->item->sizeHint();
280 Qt::Orientations exp = box
->item->expandingDirections();
281 bool empty = box
->item->isEmpty();
285 if (fixedSpacing >= 0) {
286 spacing = (previousNonEmptyIndex >= 0) ? fixedSpacing : 0;
288 if (!horz(dir) && previousNonEmptyIndex >= 0) {
289 QBoxLayoutItem *sibling = (dir == QBoxLayout::TopToBottom ? box : list.at(previousNonEmptyIndex));
291 QWidget *wid = sibling->item->widget();
293 spacing = qMax(spacing, sibling->item->geometry().top() - wid->geometry().top());
298 controlTypes1 = controlTypes2;
299 controlTypes2 = box
->item->controlTypes();
300 if (previousNonEmptyIndex >= 0) {
301 QSizePolicy::ControlTypes actual1 = controlTypes1;
302 QSizePolicy::ControlTypes actual2 = controlTypes2;
303 if (dir == QBoxLayout::RightToLeft || dir == QBoxLayout::BottomToTop)
304 qSwap(actual1, actual2);
307 spacing = style->combinedLayoutSpacing(actual1, actual2,
308 horz(dir) ? Qt::Horizontal : Qt::Vertical,
309 nullptr, q->parentWidget());
316 if (previousNonEmptyIndex >= 0)
317 a[previousNonEmptyIndex].spacing = spacing;
318 previousNonEmptyIndex = i;
321 bool ignore = empty && box
->item->widget();
324 bool expand = (exp & Qt::Horizontal || box->stretch > 0);
325 horexp = horexp || expand;
326 maxw += spacing + max.width();
327 minw += spacing + min.width();
328 hintw += spacing + hint.width();
330 qMaxExpCalc(maxh, verexp, dummy,
331 max.height(), exp & Qt::Vertical, box
->item->isEmpty());
332 minh = qMax(minh, min.height());
333 hinth = qMax(hinth, hint.height());
335 a[i].sizeHint = hint.width();
336 a[i].maximumSize = max.width();
337 a[i].minimumSize = min.width();
338 a[i].expansive = expand;
341 bool expand = (exp & Qt::Vertical || box->stretch > 0);
342 verexp = verexp || expand;
343 maxh += spacing + max.height();
344 minh += spacing + min.height();
345 hinth += spacing + hint.height();
347 qMaxExpCalc(maxw, horexp, dummy,
348 max.width(), exp & Qt::Horizontal, box
->item->isEmpty());
349 minw = qMax(minw, min.width());
350 hintw = qMax(hintw, hint.width());
352 a[i].sizeHint = hint.height();
353 a[i].maximumSize = max.height();
354 a[i].minimumSize = min.height();
355 a[i].expansive = expand;
361 hasHfw = hasHfw || box->item->hasHeightForWidth();
366 expanding = (Qt::Orientations)
367 ((horexp ? Qt::Horizontal : 0)
368 | (verexp ? Qt::Vertical : 0));
370 minSize = QSize(minw, minh);
371 maxSize = QSize(maxw, maxh).expandedTo(minSize);
372 sizeHint = QSize(hintw, hinth).expandedTo(minSize).boundedTo(maxSize);
374 q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
375 int left, top, right, bottom;
377 QSize extra(left + right, top + bottom);
758void QBoxLayout::setGeometry(
const QRect &r)
761 if (d->dirty || r != geometry()) {
762 QRect oldRect = geometry();
763 QLayout::setGeometry(r);
766 QRect cr = alignment() ? alignmentRect(r) : r;
768 int left, top, right, bottom;
769 d->effectiveMargins(&left, &top, &right, &bottom);
770 QRect s(cr.x() + left, cr.y() + top,
771 cr.width() - (left + right),
772 cr.height() - (top + bottom));
774 QList<QLayoutStruct> a = d->geomArray;
775 int pos = horz(d->dir) ? s.x() : s.y();
776 int space = horz(d->dir) ? s.width() : s.height();
778 if (d->hasHfw && !horz(d->dir)) {
779 for (
int i = 0; i < n; i++) {
780 QBoxLayoutItem *box = d->list.at(i);
781 if (box->item->hasHeightForWidth()) {
782 int width = qBound(box->item->minimumSize().width(), s.width(), box->item->maximumSize().width());
783 a[i].sizeHint = a[i].minimumSize =
784 box->item->heightForWidth(width);
789 Direction visualDir = d->dir;
790 QWidget *parent = parentWidget();
791 if (parent && parent->isRightToLeft()) {
792 if (d->dir == LeftToRight)
793 visualDir = RightToLeft;
794 else if (d->dir == RightToLeft)
795 visualDir = LeftToRight;
798 qGeomCalc(a, 0, n, pos, space);
800 bool reverse = (horz(visualDir)
801 ? ((r.right() > oldRect.right()) != (visualDir == RightToLeft))
802 : r.bottom() > oldRect.bottom());
803 for (
int j = 0; j < n; j++) {
804 int i = reverse ? n-j-1 : j;
805 QBoxLayoutItem *box = d->list.at(i);
809 box->item->setGeometry(QRect(a.at(i).pos, s.y(), a.at(i).size, s.height()));
812 box->item->setGeometry(QRect(s.left() + s.right() - a.at(i).pos - a.at(i).size + 1,
813 s.y(), a.at(i).size, s.height()));
816 box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size));
819 box->item->setGeometry(QRect(s.x(),
820 s.top() + s.bottom() - a.at(i).pos - a.at(i).size + 1,
821 s.width(), a.at(i).size));
867void QBoxLayout::insertSpacing(
int index,
int size)
870 index = d->validateIndex(index);
873 b = QLayoutPrivate::createSpacerItem(
this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
875 b = QLayoutPrivate::createSpacerItem(
this, 0, size, QSizePolicy::Minimum, QSizePolicy::Fixed);
877 QBoxLayoutItem *it =
new QBoxLayoutItem(b);
879 d->list.insert(index, it);
890void QBoxLayout::insertStretch(
int index,
int stretch)
893 index = d->validateIndex(index);
896 b = QLayoutPrivate::createSpacerItem(
this, 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
898 b = QLayoutPrivate::createSpacerItem(
this, 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
900 QBoxLayoutItem *it =
new QBoxLayoutItem(b, stretch);
902 d->list.insert(index, it);
1166void QBoxLayout::setDirection(Direction direction)
1169 if (d->dir == direction)
1171 if (horz(d->dir) != horz(direction)) {
1176 for (
int i = 0; i < d->list.size(); ++i) {
1177 QBoxLayoutItem *box = d->list.at(i);
1179 QSpacerItem *sp = box->item->spacerItem();
1181 if (sp->expandingDirections() == Qt::Orientations{} ) {
1183 QSize s = sp->sizeHint();
1184 sp->changeSize(s.height(), s.width(),
1185 horz(direction) ? QSizePolicy::Fixed:QSizePolicy::Minimum,
1186 horz(direction) ? QSizePolicy::Minimum:QSizePolicy::Fixed);
1190 if (horz(direction))
1191 sp->changeSize(0, 0, QSizePolicy::Expanding,
1192 QSizePolicy::Minimum);
1194 sp->changeSize(0, 0, QSizePolicy::Minimum,
1195 QSizePolicy::Expanding);