File indexing completed on 2024-04-28 15:27:44

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"