10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
79Q_STATIC_LOGGING_CATEGORY(lcLayouts,
"qt.quick.layouts")
82QQuickLayoutItemProxy::QQuickLayoutItemProxy(QQuickItem *parent)
83 : QQuickItem(*
new QQuickLayoutItemProxyPrivate, parent)
90 Q_D(QQuickLayoutItemProxy);
100 d->target->setParentItem(
nullptr);
109
110
111
114 QQuickItem::geometryChange(newGeom, oldGeom);
118 const QSizeF sz = newGeom.size();
121 if (QQuickItem *t = effectiveTarget()) {
129 if (t->parentItem() !=
this)
130 pos = t->parentItem()->mapFromGlobal(mapToGlobal(0, 0));
132 if (t->size() == sz && t->position() == pos && newGeom == oldGeom)
141
142
143
146 if (c == QQuickItem::ItemVisibleHasChanged)
150 QQuickItem::itemChange(c, d);
159#define propertyForwarding(property, Property)
160 void QQuickLayoutItemProxy::target##Property##Changed() {
161 Q_D(QQuickLayoutItemProxy);
162 QQuickLayoutAttached *attTarget = attachedLayoutObject(target(), false);
163 QQuickLayoutAttached *attProxy = attachedLayoutObject(this, false);
164 if (!attTarget) return;
165 if (attProxy->property() == attTarget->property())
167 d->m_expectProxy##Property##Change = true;
168 attProxy->set##Property(attTarget->property());
170 void QQuickLayoutItemProxy::proxy##Property##Changed() {
171 Q_D(QQuickLayoutItemProxy);
172 if (d->m_expectProxy##Property##Change) {
173 d->m_expectProxy##Property##Change = false;
176 QQuickLayoutAttached *attTarget = attachedLayoutObject(target(), false);
177 if (!attTarget) return;
178 disconnect(attTarget, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::target##Property##Changed);
198#undef propertyForwarding
201
202
203
204
205
208
209
210
213 Q_D(
const QQuickLayoutItemProxy);
218
219
220
221
222
223
224
227 Q_D(QQuickLayoutItemProxy);
229 if (newTarget == d->target)
232 if (d->target && d->target->property(
"QQuickLayoutItemProxyAttachedData").isValid()) {
233 QQuickLayoutItemProxyAttachedData *attachedData = d->target->property(
"QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>();
234 attachedData->releaseProxy(
this);
236 d->target = newTarget;
240 QQuickLayoutItemProxyAttachedData *attachedData;
241 if (newTarget->property(
"QQuickLayoutItemProxyAttachedData").isValid()) {
242 attachedData = newTarget->property(
"QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>();
244 attachedData =
new QQuickLayoutItemProxyAttachedData(newTarget);
246 v.setValue(attachedData);
247 newTarget->setProperty(
"QQuickLayoutItemProxyAttachedData", v);
249 attachedData->registerProxy(
this);
252 if (!attachedData->proxyHasControl())
253 newTarget->setVisible(
false);
257 if (QQuickLayoutAttached *attTarget = attachedLayoutObject(newTarget)) {
258 QQuickLayoutAttached *attProxy = attachedLayoutObject(
this,
true);
260 disconnect(attTarget,
nullptr, attProxy,
nullptr);
264#define connectPropertyForwarding(property, Property)
265 if (!attProxy->is##Property##Set()) {
266 connect(attTarget, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::target##Property##Changed);
267 connect(attProxy, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::proxy##Property##Changed);
268 target##Property##Changed();
286#undef connectPropertyForwarding
289 auto fnBindImplW = [newTarget,
this](){
this->setImplicitWidth(newTarget->implicitWidth()); };
291 connect(newTarget, &QQuickItem::implicitWidthChanged, fnBindImplW);
294 auto fnBindImplH = [newTarget,
this](){
this->setImplicitHeight(newTarget->implicitHeight()); };
296 connect(newTarget, &QQuickItem::implicitHeightChanged, fnBindImplH);
303 emit targetChanged();
307
308
309
312 if (target() ==
nullptr)
316 return (attachedData->getControllingProxy() ==
this) ? target() :
nullptr;
320
321
322
323
324
331
332
333
334
335
336
337
338
341 Q_D(QQuickLayoutItemProxy);
348 d->target->setVisible(
true);
349 d->target->setParentItem(
this);
354 if (d->target->parentItem() ==
this) {
355 d->target->setParentItem(
nullptr);
357 qCDebug(lcLayouts) <<
"Parent was changed to" << d->target->parentItem() <<
"while an ItemProxy had control";
358 d->target->setVisible(
false);
364
365
366
373 if (attachedData->getControllingProxy() ==
this)
374 geometryChange(boundingRect(), boundingRect());
380 : QQuickItemPrivate(),
402
403
404
405
406
407
408
409
411 : QObject(parent), controllingProxy(
nullptr)
418 if (QObject *par = parent())
419 par->setProperty(
"QQuickLayoutItemProxyAttachedData", QVariant());
423 for (
auto &proxy: std::as_const(proxies))
424 proxy->clearTarget();
428
429
430
431
432
433
436 if (proxies.contains(proxy))
439 proxies.append(proxy);
440 emit proxiesChanged();
444
445
446
449 if (proxy == controllingProxy)
452 proxies.removeAll(proxy);
454 if (proxies.isEmpty())
457 emit proxiesChanged();
461
462
463
464
465
466
467
468
471 if (controllingProxy || !proxies.contains(proxy))
474 qCDebug(lcLayouts) << proxy
475 <<
"takes control of"
478 controllingProxy = proxy;
480 emit controllingProxyChanged();
485
486
487
488
489
492 if (controllingProxy != proxy)
495 qCDebug(lcLayouts) << proxy
496 <<
"no longer controls"
499 controllingProxy =
nullptr;
500 emit controlReleased();
501 emit controllingProxyChanged();
503 for (
auto &otherProxy: std::as_const(proxies)) {
504 if (proxy != otherProxy)
505 otherProxy->maybeTakeControl();
510
511
512
513
516 return controllingProxy;
520
521
522
526 using Property = QQmlListProperty<Type>;
530 [](Property *p) {
return static_cast<QList<Type *> *>(p->data)->size(); },
531 [](Property *p, qsizetype i) {
return static_cast<QList<Type *> *>(p->data)->at(i); }
536
537
538
541 return controllingProxy !=
nullptr;
Provides attached properties for items that are managed by one or more LayoutItemProxy.
QQmlListProperty< QQuickLayoutItemProxy > getProxies()
QQuickLayoutItemProxyAttachedData::getProxies.
void registerProxy(QQuickLayoutItemProxy *proxy)
QQuickLayoutItemProxyAttachedData::registerProxy registers a proxy that manages the item this data is...
void releaseControl(QQuickLayoutItemProxy *proxy)
QQuickLayoutItemProxyAttachedData::releaseControl is called by LayoutItemProxies when they try no lon...
bool proxyHasControl() const
QQuickLayoutItemProxyAttachedData::proxyHasControl.
~QQuickLayoutItemProxyAttachedData() override
bool takeControl(QQuickLayoutItemProxy *proxy)
QQuickLayoutItemProxyAttachedData::takeControl is called by LayoutItemProxies when they try to take c...
void releaseProxy(QQuickLayoutItemProxy *proxy)
QQuickLayoutItemProxyAttachedData::releaseProxy removes a proxy from a list of known proxies that man...
QQuickLayoutItemProxy * getControllingProxy() const
QQuickLayoutItemProxyAttachedData::getControllingProxy.
unsigned m_expectProxyMarginsChange
unsigned m_expectProxyFillHeightChange
unsigned m_expectProxyPreferredHeightChange
unsigned m_expectProxyMaximumHeightChange
unsigned m_expectProxyTopMarginChange
unsigned m_expectProxyBottomMarginChange
unsigned m_expectProxyFillWidthChange
unsigned m_expectProxyMinimumHeightChange
unsigned m_expectProxyRightMarginChange
unsigned m_expectProxyLeftMarginChange
unsigned m_expectProxyMinimumWidthChange
unsigned m_expectProxyPreferredWidthChange
unsigned m_expectProxyVerticalStretchFactorChange
unsigned m_expectProxyMaximumWidthChange
unsigned m_expectProxyHorizontalStretchFactorChange
unsigned m_expectProxyAlignmentChange
void clearTarget()
QQuickLayoutItemProxy::clearTarget sets the target to null.
void geometryChange(const QRectF &newGeom, const QRectF &oldGeom) override
QQuickLayoutItemProxy::geometryChange Reimplementation of QQuickItem::geometryChange to update the ta...
QQuickItem * target() const
\qmlproperty Item LayoutItemProxy::target
void itemChange(ItemChange c, const ItemChangeData &d) override
QQuickLayoutItemProxy::itemChange is a reimplementation of QQuickItem::itemChange to react to changes...
void maybeTakeControl()
QQuickLayoutItemProxy::maybeTakeControl checks and takes over control of the item.
~QQuickLayoutItemProxy() override
#define connectPropertyForwarding(property, Property)
#define propertyForwarding(property, Property)