File indexing completed on 2024-04-28 11:42:26
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <QQmlProperty> 0008 0009 #include "sizegroup.h" 0010 0011 #define pThis (static_cast<SizeGroup *>(prop->object)) 0012 0013 void SizeGroup::appendItem(QQmlListProperty<QQuickItem> *prop, QQuickItem *value) 0014 { 0015 pThis->m_items << value; 0016 pThis->connectItem(value); 0017 } 0018 0019 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0020 int SizeGroup::itemCount(QQmlListProperty<QQuickItem> *prop) 0021 #else 0022 qsizetype SizeGroup::itemCount(QQmlListProperty<QQuickItem> *prop) 0023 #endif 0024 { 0025 return pThis->m_items.count(); 0026 } 0027 0028 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0029 QQuickItem *SizeGroup::itemAt(QQmlListProperty<QQuickItem> *prop, int index) 0030 #else 0031 QQuickItem *SizeGroup::itemAt(QQmlListProperty<QQuickItem> *prop, qsizetype index) 0032 #endif 0033 { 0034 return pThis->m_items[index]; 0035 } 0036 0037 void SizeGroup::clearItems(QQmlListProperty<QQuickItem> *prop) 0038 { 0039 for (const auto &item : std::as_const(pThis->m_items)) { 0040 QObject::disconnect(pThis->m_connections[item].first); 0041 QObject::disconnect(pThis->m_connections[item].second); 0042 } 0043 pThis->m_items.clear(); 0044 } 0045 0046 void SizeGroup::connectItem(QQuickItem *item) 0047 { 0048 auto conn1 = connect(item, &QQuickItem::implicitWidthChanged, this, [this]() { 0049 adjustItems(Mode::Width); 0050 }); 0051 auto conn2 = connect(item, &QQuickItem::implicitHeightChanged, this, [this]() { 0052 adjustItems(Mode::Height); 0053 }); 0054 m_connections[item] = qMakePair(conn1, conn2); 0055 adjustItems(m_mode); 0056 } 0057 0058 QQmlListProperty<QQuickItem> SizeGroup::items() 0059 { 0060 return QQmlListProperty<QQuickItem>(this, // 0061 nullptr, 0062 appendItem, 0063 itemCount, 0064 itemAt, 0065 clearItems); 0066 } 0067 0068 void SizeGroup::relayout() 0069 { 0070 adjustItems(Mode::Both); 0071 } 0072 0073 void SizeGroup::componentComplete() 0074 { 0075 adjustItems(Mode::Both); 0076 } 0077 0078 void SizeGroup::adjustItems(Mode whatChanged) 0079 { 0080 if (m_mode == Mode::Width && whatChanged == Mode::Height) { 0081 return; 0082 } 0083 if (m_mode == Mode::Height && whatChanged == Mode::Width) { 0084 return; 0085 } 0086 0087 qreal maxHeight = 0.0; 0088 qreal maxWidth = 0.0; 0089 0090 for (const auto &item : std::as_const(m_items)) { 0091 if (item == nullptr) { 0092 continue; 0093 } 0094 0095 switch (m_mode) { 0096 case Mode::Width: 0097 maxWidth = qMax(maxWidth, item->implicitWidth()); 0098 break; 0099 case Mode::Height: 0100 maxHeight = qMax(maxHeight, item->implicitHeight()); 0101 break; 0102 case Mode::Both: 0103 maxWidth = qMax(maxWidth, item->implicitWidth()); 0104 maxHeight = qMax(maxHeight, item->implicitHeight()); 0105 break; 0106 case Mode::None: 0107 break; 0108 } 0109 } 0110 0111 for (const auto &item : std::as_const(m_items)) { 0112 if (item == nullptr) { 0113 continue; 0114 } 0115 0116 if (!qmlEngine(item) || !qmlContext(item)) { 0117 continue; 0118 } 0119 0120 switch (m_mode) { 0121 case Mode::Width: 0122 QQmlProperty(item, QStringLiteral("Layout.preferredWidth"), qmlContext(item)).write(maxWidth); 0123 break; 0124 case Mode::Height: 0125 QQmlProperty(item, QStringLiteral("Layout.preferredHeight"), qmlContext(item)).write(maxHeight); 0126 break; 0127 case Mode::Both: 0128 QQmlProperty(item, QStringLiteral("Layout.preferredWidth"), qmlContext(item)).write(maxWidth); 0129 QQmlProperty(item, QStringLiteral("Layout.preferredHeight"), qmlContext(item)).write(maxHeight); 0130 break; 0131 case Mode::None: 0132 break; 0133 } 0134 } 0135 } 0136 0137 #include "moc_sizegroup.cpp"