1/*
2 * SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include <QQmlProperty>
8
9#include "sizegroup.h"
10
11#define pThis (static_cast<SizeGroup *>(prop->object))
12
13void SizeGroup::appendItem(QQmlListProperty<QQuickItem> *prop, QQuickItem *value)
14{
15 pThis->m_items << value;
16 pThis->connectItem(item: value);
17}
18
19qsizetype SizeGroup::itemCount(QQmlListProperty<QQuickItem> *prop)
20{
21 return pThis->m_items.count();
22}
23
24QQuickItem *SizeGroup::itemAt(QQmlListProperty<QQuickItem> *prop, qsizetype index)
25{
26 return pThis->m_items[index];
27}
28
29void SizeGroup::clearItems(QQmlListProperty<QQuickItem> *prop)
30{
31 for (const auto &item : std::as_const(pThis->m_items)) {
32 QObject::disconnect(pThis->m_connections[item].first);
33 QObject::disconnect(pThis->m_connections[item].second);
34 }
35 pThis->m_items.clear();
36}
37
38void SizeGroup::connectItem(QQuickItem *item)
39{
40 auto conn1 = connect(sender: item, signal: &QQuickItem::implicitWidthChanged, context: this, slot: [this]() {
41 adjustItems(whatChanged: Mode::Width);
42 });
43 auto conn2 = connect(sender: item, signal: &QQuickItem::implicitHeightChanged, context: this, slot: [this]() {
44 adjustItems(whatChanged: Mode::Height);
45 });
46 m_connections[item] = qMakePair(value1&: conn1, value2&: conn2);
47 adjustItems(whatChanged: m_mode);
48}
49
50QQmlListProperty<QQuickItem> SizeGroup::items()
51{
52 return QQmlListProperty<QQuickItem>(this, //
53 nullptr,
54 appendItem,
55 itemCount,
56 itemAt,
57 clearItems);
58}
59
60void SizeGroup::relayout()
61{
62 adjustItems(whatChanged: Mode::Both);
63}
64
65void SizeGroup::componentComplete()
66{
67 adjustItems(whatChanged: Mode::Both);
68}
69
70void SizeGroup::adjustItems(Mode whatChanged)
71{
72 if (m_mode == Mode::Width && whatChanged == Mode::Height) {
73 return;
74 }
75 if (m_mode == Mode::Height && whatChanged == Mode::Width) {
76 return;
77 }
78
79 qreal maxHeight = 0.0;
80 qreal maxWidth = 0.0;
81
82 for (const auto &item : std::as_const(t&: m_items)) {
83 if (item == nullptr) {
84 continue;
85 }
86
87 switch (m_mode) {
88 case Mode::Width:
89 maxWidth = qMax(a: maxWidth, b: item->implicitWidth());
90 break;
91 case Mode::Height:
92 maxHeight = qMax(a: maxHeight, b: item->implicitHeight());
93 break;
94 case Mode::Both:
95 maxWidth = qMax(a: maxWidth, b: item->implicitWidth());
96 maxHeight = qMax(a: maxHeight, b: item->implicitHeight());
97 break;
98 case Mode::None:
99 break;
100 }
101 }
102
103 for (const auto &item : std::as_const(t&: m_items)) {
104 if (item == nullptr) {
105 continue;
106 }
107
108 if (!qmlEngine(item) || !qmlContext(item)) {
109 continue;
110 }
111
112 switch (m_mode) {
113 case Mode::Width:
114 QQmlProperty(item, QStringLiteral("Layout.preferredWidth"), qmlContext(item)).write(maxWidth);
115 break;
116 case Mode::Height:
117 QQmlProperty(item, QStringLiteral("Layout.preferredHeight"), qmlContext(item)).write(maxHeight);
118 break;
119 case Mode::Both:
120 QQmlProperty(item, QStringLiteral("Layout.preferredWidth"), qmlContext(item)).write(maxWidth);
121 QQmlProperty(item, QStringLiteral("Layout.preferredHeight"), qmlContext(item)).write(maxHeight);
122 break;
123 case Mode::None:
124 break;
125 }
126 }
127}
128
129#include "moc_sizegroup.cpp"
130

source code of kirigami/src/sizegroup.cpp