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