File indexing completed on 2024-05-12 16:02:30

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2021 Agata Cacko <cacko.azh@gmail.com>
0003  * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
0004  *
0005  * SPDX-License-Identifier: GPL-3.0-or-later
0006  */
0007 
0008 #include <QtWidgets>
0009 #include <KisWrappableHBoxLayout.h>
0010 
0011 
0012 KisWrappableHBoxLayout::KisWrappableHBoxLayout(QWidget *parent)
0013     : QLayout(parent)
0014 {
0015     // Remove extra floating space.
0016     setContentsMargins(0, 0, 0, 0);
0017 }
0018 
0019 KisWrappableHBoxLayout::~KisWrappableHBoxLayout()
0020 {
0021     QLayoutItem *item;
0022     while ((item = takeAt(0))) {
0023         delete item;
0024     }
0025 }
0026 
0027 void KisWrappableHBoxLayout::addItem(QLayoutItem *item)
0028 {
0029     m_items.append(item);
0030 }
0031 
0032 QSize KisWrappableHBoxLayout::sizeHint() const
0033 {
0034     const QMargins margins = contentsMargins();
0035     if (!geometry().isEmpty()) {
0036         return QSize(geometry().width(), heightForWidth(geometry().width()))
0037                 + QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
0038     }
0039     return minimumSize();
0040 }
0041 
0042 QSize KisWrappableHBoxLayout::minimumSize() const
0043 {
0044     const QMargins margins = contentsMargins();
0045     const QSize marginsSize = QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
0046 
0047     QSize size;
0048     for (const QLayoutItem *item : qAsConst(m_items))
0049         size = size.expandedTo(item->minimumSize());
0050 
0051     if (!geometry().isEmpty()) {
0052         QSize optimal = QSize(geometry().width(), heightForWidth(geometry().width()));
0053         int minimumWidth = size.width(); // cannot be smaller than the biggest item
0054         int minimumHeight = qMax(size.height(), optimal.height());
0055         QSize minimum = QSize(minimumWidth, minimumHeight);
0056         return minimum;
0057     }
0058 
0059     size += marginsSize;
0060     //size = QSize(size.width(), size.height()*5);
0061     return size;
0062 }
0063 
0064 int KisWrappableHBoxLayout::count() const
0065 {
0066     return m_items.size();
0067 }
0068 
0069 
0070 
0071 QLayoutItem *KisWrappableHBoxLayout::itemAt(int idx) const
0072 {
0073     return m_items.value(idx);
0074 }
0075 
0076 QLayoutItem *KisWrappableHBoxLayout::takeAt(int idx)
0077 {
0078     return idx >= 0 && idx < m_items.size() ? m_items.takeAt(idx) : 0;
0079 }
0080 
0081 void KisWrappableHBoxLayout::setGeometry(const QRect &rect)
0082 {
0083     QLayout::setGeometry(rect);
0084     doLayout(rect, false);
0085 }
0086 
0087 bool KisWrappableHBoxLayout::hasHeightForWidth() const
0088 {
0089     return true;
0090 }
0091 
0092 int KisWrappableHBoxLayout::heightForWidth(int width) const
0093 {
0094     int height = doLayout(QRect(0, 0, width, 0), true);
0095     return height;
0096 }
0097 
0098 int KisWrappableHBoxLayout::doLayout(const QRect &rect, bool testOnly) const
0099 {
0100     int left, top, right, bottom;
0101     getContentsMargins(&left, &top, &right, &bottom);
0102     QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
0103     int x = effectiveRect.x();
0104     int y = effectiveRect.y();
0105     int lineHeight = 0;
0106 
0107     for (QLayoutItem *item : qAsConst(m_items)) {
0108         int nextX = x + item->sizeHint().width() + spacing();
0109         if (nextX - spacing() > effectiveRect.right() && lineHeight > 0) {
0110             x = effectiveRect.x();
0111             y = y + lineHeight + spacing();
0112             nextX = x + item->sizeHint().width() + spacing();
0113             lineHeight = 0;
0114         }
0115 
0116         if (!testOnly) {
0117             item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
0118         }
0119 
0120         x = nextX;
0121         lineHeight = qMax(lineHeight, item->sizeHint().height());
0122     }
0123     return y + lineHeight - rect.y() + bottom;
0124 }
0125