1 | // Copyright (C) 2023 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | #include "qquicklayoutitemproxy_p.h" |
4 | #include "qquicklayout_p.h" |
5 | |
6 | /*! |
7 | \qmltype LayoutItemProxy |
8 | \nativetype QQuickLayoutItemProxy |
9 | \inherits Item |
10 | \inqmlmodule QtQuick.Layouts |
11 | \ingroup layouts |
12 | \since QtQuick.Layouts 6.6 |
13 | \brief The LayoutItemProxy class provides a placeholder for \l{QQuickItem}s |
14 | in layouts. |
15 | |
16 | Some responsive layouts require different layout hierarchies for different |
17 | screen sizes, but the layout hierarchy is the same as the QML structure and |
18 | can therefore not be changed at runtime. LayoutItemProxy overcomes this |
19 | limitation by representing a \l{target} item within the layout. The |
20 | \l{target} item itself can be defined anywhere in the QML hierarchy. This |
21 | allows declaration of multiple layouts with the same content items. The |
22 | layouts can be shown and hidden to switch between them. |
23 | |
24 | The LayoutItemProxy will try to take control of the \l{target} item if it |
25 | is \l [QML] {Item::}{visible}. Taking control will position and resize the |
26 | \l{target} item to match the position and size of the LayoutItemProxy. |
27 | Further, the LayoutItemProxy will set itself as the parent of the |
28 | \l{target} (to ensure event delivery and useful drawing order) and set the |
29 | visibility to \c true. Multiple LayoutItemProxies can \l{target} the same |
30 | item, but only one LayoutItemProxy can control an item at a time. Therefore |
31 | only one of the proxies targeting the same item should be visible at a |
32 | time. If multiple proxies target the same item but \e visible is set to |
33 | false for each proxy, the item will also be invisible. |
34 | |
35 | All \l{Layout} attached properties of the \l {target}, as well as the |
36 | \l{QQuickItem::implicitWidth} and \l{QQuickItem::implicitHeight} of the |
37 | \l{target} are forwarded by the LayoutItemProxy. The LayoutItemProxy will |
38 | mimic the \l{target} as closely as possible in terms of \l{Layout} |
39 | properties and size. \l{Layout} attached properties can also be set |
40 | explicitly on the LayoutItemProxy which will stop the forwarding of the |
41 | \l {target} properties. |
42 | |
43 | \section1 Example Usage |
44 | |
45 | This is a minimalistic example, changing between two layouts using proxies |
46 | to use the same items in both layouts. The items that populate the layouts |
47 | can be defined at an arbitrary point in the QML structure. |
48 | |
49 | \snippet layouts/simpleProxy.qml item definition |
50 | |
51 | Then we can define the Layouts with LayoutItemProxys |
52 | |
53 | \snippet layouts/simpleProxy.qml layout definition |
54 | |
55 | We can switch now between the layouts, depending on a criterion of our |
56 | choice by toggling the visibility of the layouts on and off. |
57 | |
58 | \snippet layouts/simpleProxy.qml layout choice |
59 | |
60 | The two resulting layouts look like this: |
61 | |
62 | \div {class="float-right"} |
63 | \inlineimage simpleProxy.png |
64 | \enddiv |
65 | |
66 | The LayoutItemProxy can also be used without layouts, e.g. by anchoring it |
67 | to different items. A mix of real \l {Item}{Items} and proxy items is |
68 | equally possible, as well as nested structures of layouts and items. |
69 | |
70 | \warning The LayoutItemProxy will set the parent of its target to itself. |
71 | Keep this in mind when referring to the parent of the target item. |
72 | |
73 | \sa Item, GridLayout, RowLayout, ColumnLayout |
74 | */ |
75 | |
76 | Q_LOGGING_CATEGORY(lcLayouts, "qt.quick.layouts") |
77 | |
78 | |
79 | QQuickLayoutItemProxy::QQuickLayoutItemProxy(QQuickItem *parent) |
80 | : QQuickItem(*new QQuickLayoutItemProxyPrivate, parent) |
81 | { |
82 | |
83 | } |
84 | |
85 | QQuickLayoutItemProxy::~QQuickLayoutItemProxy() |
86 | { |
87 | Q_D(QQuickLayoutItemProxy); |
88 | |
89 | if (!d->target) |
90 | return; |
91 | |
92 | QQuickLayoutItemProxyAttachedData * attachedData = d->target->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>(); |
93 | // De-register this proxy from the proxies controlling the target |
94 | if (attachedData) { |
95 | if (attachedData->getControllingProxy() == this) { |
96 | attachedData->releaseControl(proxy: this); |
97 | d->target->setParentItem(nullptr); |
98 | } |
99 | attachedData->releaseProxy(proxy: this); |
100 | } |
101 | // The target item still has a QObject parent that takes care of its destrctuion. |
102 | // No need to invoke destruction of the target tiem from here. |
103 | } |
104 | |
105 | /*! \internal |
106 | \brief QQuickLayoutItemProxy::geometryChange Reimplementation of |
107 | QQuickItem::geometryChange to update the target geometry too. |
108 | */ |
109 | void QQuickLayoutItemProxy::geometryChange(const QRectF &newGeom, const QRectF &oldGeom) |
110 | { |
111 | QQuickItem::geometryChange(newGeometry: newGeom, oldGeometry: oldGeom); |
112 | if (!isVisible()) |
113 | return; |
114 | |
115 | const QSizeF sz = newGeom.size(); |
116 | QPointF pos(0., 0.); |
117 | |
118 | if (QQuickItem *t = effectiveTarget()) { |
119 | if (QQuickLayoutItemProxyAttachedData * attachedData = target()->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>()) { |
120 | if (attachedData->getControllingProxy() != this) |
121 | return; |
122 | } |
123 | |
124 | // Should normally not be the case, except the user resets the parent |
125 | // This is a failsave for this case and positions the item correctly |
126 | if (t->parentItem() != this) |
127 | pos = t->parentItem()->mapFromGlobal(point: mapToGlobal(x: 0, y: 0)); |
128 | |
129 | if (t->size() == sz && t->position() == pos && newGeom == oldGeom) |
130 | return; |
131 | |
132 | t->setSize(sz); |
133 | t->setPosition(pos); |
134 | } |
135 | } |
136 | |
137 | /*! \internal |
138 | \brief QQuickLayoutItemProxy::itemChange is a reimplementation of |
139 | QQuickItem::itemChange to react to changes in visibility. |
140 | */ |
141 | void QQuickLayoutItemProxy::itemChange(ItemChange c, const ItemChangeData &d) |
142 | { |
143 | if (c == QQuickItem::ItemVisibleHasChanged) |
144 | { |
145 | maybeTakeControl(); |
146 | } |
147 | QQuickItem::itemChange(c, d); |
148 | } |
149 | |
150 | // Implementation of the slots to react to changes of the Layout attached properties. |
151 | // If the target Layout propertie change, we change the proxy Layout properties accordingly |
152 | // If the proxy Layout properties have been changed externally, we want to remove this binding. |
153 | // The member variables m_expectProxy##Property##Change help us keep track about who invokes |
154 | // the change of the parameter. If it is invoked by the target we expect a proxy property |
155 | // change and will not remove the connection. |
156 | #define propertyForwarding(property, Property) \ |
157 | void QQuickLayoutItemProxy::target##Property##Changed() { \ |
158 | Q_D(QQuickLayoutItemProxy); \ |
159 | QQuickLayoutAttached *attTarget = attachedLayoutObject(target(), false); \ |
160 | QQuickLayoutAttached *attProxy = attachedLayoutObject(this, false); \ |
161 | if (!attTarget) return; \ |
162 | if (attProxy->property() == attTarget->property()) \ |
163 | return; \ |
164 | d->m_expectProxy##Property##Change = true; \ |
165 | attProxy->set##Property(attTarget->property()); \ |
166 | } \ |
167 | void QQuickLayoutItemProxy::proxy##Property##Changed() { \ |
168 | Q_D(QQuickLayoutItemProxy); \ |
169 | if (d->m_expectProxy##Property##Change) { \ |
170 | d->m_expectProxy##Property##Change = false; \ |
171 | return; \ |
172 | } \ |
173 | QQuickLayoutAttached *attTarget = attachedLayoutObject(target(), false); \ |
174 | if (!attTarget) return; \ |
175 | disconnect(attTarget, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::target##Property##Changed); \ |
176 | } |
177 | |
178 | propertyForwarding(minimumWidth, MinimumWidth) |
179 | propertyForwarding(minimumHeight, MinimumHeight) |
180 | propertyForwarding(preferredWidth, PreferredWidth) |
181 | propertyForwarding(preferredHeight, PreferredHeight) |
182 | propertyForwarding(maximumWidth, MaximumWidth) |
183 | propertyForwarding(maximumHeight, MaximumHeight) |
184 | propertyForwarding(fillWidth, FillWidth) |
185 | propertyForwarding(fillHeight, FillHeight) |
186 | propertyForwarding(alignment, Alignment) |
187 | propertyForwarding(horizontalStretchFactor, HorizontalStretchFactor) |
188 | propertyForwarding(verticalStretchFactor, VerticalStretchFactor) |
189 | propertyForwarding(margins, Margins) |
190 | propertyForwarding(leftMargin, LeftMargin) |
191 | propertyForwarding(topMargin, TopMargin) |
192 | propertyForwarding(rightMargin, RightMargin) |
193 | propertyForwarding(bottomMargin, BottomMargin) |
194 | |
195 | #undef propertyForwarding |
196 | |
197 | /*! |
198 | \qmlproperty Item LayoutItemProxy::target |
199 | |
200 | This property holds the \l Item that the proxy should represent in a |
201 | \l {Layout} hierarchy. |
202 | */ |
203 | |
204 | /*! \internal |
205 | \brief QQuickLayoutItemProxy::target |
206 | \return The target item of the proxy |
207 | */ |
208 | QQuickItem *QQuickLayoutItemProxy::target() const |
209 | { |
210 | Q_D(const QQuickLayoutItemProxy); |
211 | return d->target; |
212 | } |
213 | |
214 | /*! \internal |
215 | \brief QQuickLayoutItemProxy::setTarget sets the target |
216 | \param newTarget The item that the proxy stands in place for. |
217 | |
218 | All layout properties of the target are connected to the layout properties |
219 | of the LayoutItemProxy. It the LayoutItemProxy is visible, it will try to |
220 | take control of the target. |
221 | */ |
222 | void QQuickLayoutItemProxy::setTarget(QQuickItem *newTarget) |
223 | { |
224 | Q_D(QQuickLayoutItemProxy); |
225 | |
226 | if (newTarget == d->target) |
227 | return; |
228 | |
229 | d->target = newTarget; |
230 | |
231 | if (newTarget) { |
232 | |
233 | QQuickLayoutItemProxyAttachedData *attachedData; |
234 | if (newTarget->property(name: "QQuickLayoutItemProxyAttachedData").isValid()) { |
235 | attachedData = newTarget->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>(); |
236 | } else { |
237 | attachedData = new QQuickLayoutItemProxyAttachedData(newTarget); |
238 | QVariant v; |
239 | v.setValue(attachedData); |
240 | newTarget->setProperty(name: "QQuickLayoutItemProxyAttachedData", value: v); |
241 | } |
242 | attachedData->registerProxy(proxy: this); |
243 | |
244 | // If there is no other controlling proxy, we will hide the target |
245 | if (!attachedData->proxyHasControl()) |
246 | newTarget->setVisible(false); |
247 | // We are calling maybeTakeControl at the end to eventually take |
248 | // responsibility of showing the target. |
249 | |
250 | if (QQuickLayoutAttached *attTarget = attachedLayoutObject(item: newTarget)) { |
251 | QQuickLayoutAttached *attProxy = attachedLayoutObject(item: this, create: true); |
252 | |
253 | disconnect(sender: attTarget, signal: nullptr, receiver: attProxy, member: nullptr); |
254 | |
255 | // bind item-specific layout properties: |
256 | |
257 | #define connectPropertyForwarding(property, Property) \ |
258 | if (!attProxy->is##Property##Set()) { \ |
259 | connect(attTarget, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::target##Property##Changed); \ |
260 | connect(attProxy, &QQuickLayoutAttached::property##Changed, this, &QQuickLayoutItemProxy::proxy##Property##Changed); \ |
261 | target##Property##Changed(); \ |
262 | } |
263 | connectPropertyForwarding(minimumWidth, MinimumWidth) |
264 | connectPropertyForwarding(minimumHeight, MinimumHeight) |
265 | connectPropertyForwarding(preferredWidth, PreferredWidth) |
266 | connectPropertyForwarding(preferredHeight, PreferredHeight) |
267 | connectPropertyForwarding(maximumWidth, MaximumWidth) |
268 | connectPropertyForwarding(maximumHeight, MaximumHeight) |
269 | connectPropertyForwarding(fillWidth, FillWidth) |
270 | connectPropertyForwarding(fillHeight, FillHeight) |
271 | connectPropertyForwarding(alignment, Alignment) |
272 | connectPropertyForwarding(horizontalStretchFactor, HorizontalStretchFactor) |
273 | connectPropertyForwarding(verticalStretchFactor, VerticalStretchFactor) |
274 | connectPropertyForwarding(margins, Margins) |
275 | connectPropertyForwarding(leftMargin, LeftMargin) |
276 | connectPropertyForwarding(topMargin, TopMargin) |
277 | connectPropertyForwarding(rightMargin, RightMargin) |
278 | connectPropertyForwarding(bottomMargin, BottomMargin) |
279 | #undef connectPropertyForwarding |
280 | |
281 | // proxy.implicitWidth: target.implicitWidth |
282 | auto fnBindImplW = [newTarget, this](){ this->setImplicitWidth(newTarget->implicitWidth()); }; |
283 | fnBindImplW(); |
284 | connect(sender: newTarget, signal: &QQuickItem::implicitWidthChanged, slot&: fnBindImplW); |
285 | |
286 | // proxy.implicitHeight: target.implicitHeight |
287 | auto fnBindImplH = [newTarget, this](){ this->setImplicitHeight(newTarget->implicitHeight()); }; |
288 | fnBindImplH(); |
289 | connect(sender: newTarget, signal: &QQuickItem::implicitHeightChanged, slot&: fnBindImplH); |
290 | } |
291 | } |
292 | |
293 | if (isVisible()) |
294 | maybeTakeControl(); |
295 | |
296 | emit targetChanged(); |
297 | } |
298 | |
299 | /*! \internal |
300 | \brief QQuickLayoutItemProxy::effectiveTarget |
301 | \return The target item of the proxy if it is in control, \c null otherwise. |
302 | */ |
303 | QQuickItem *QQuickLayoutItemProxy::effectiveTarget() const |
304 | { |
305 | if (target() == nullptr) |
306 | return nullptr; |
307 | |
308 | QQuickLayoutItemProxyAttachedData * attachedData = target()->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>(); |
309 | return (attachedData->getControllingProxy() == this) ? target() : nullptr; |
310 | } |
311 | |
312 | /*! \internal |
313 | \brief QQuickLayoutItemProxy::clearTarget sets the target to null. |
314 | |
315 | This function is called if the target is destroyed to make sure we do not |
316 | try to access a non-existing object. |
317 | */ |
318 | void QQuickLayoutItemProxy::clearTarget() |
319 | { |
320 | setTarget(nullptr); |
321 | } |
322 | |
323 | /*! \internal |
324 | \brief QQuickLayoutItemProxy::maybeTakeControl checks and takes over control |
325 | of the item. |
326 | |
327 | If the proxy is visible it will try to take control over the target and set |
328 | its visibility to true. If the proxy is hidden it will also hide the target |
329 | and another LayoutItemProxy has to set the visibility to \c true or the |
330 | target will stay invisible. |
331 | */ |
332 | void QQuickLayoutItemProxy::maybeTakeControl() |
333 | { |
334 | Q_D(QQuickLayoutItemProxy); |
335 | if (!d->target) |
336 | return; |
337 | |
338 | QQuickLayoutItemProxyAttachedData * attachedData = d->target->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>(); |
339 | if (isVisible() && attachedData->getControllingProxy() != this) { |
340 | if (attachedData->takeControl(proxy: this)) { |
341 | d->target->setVisible(true); |
342 | d->target->setParentItem(this); |
343 | updatePos(); |
344 | } |
345 | } |
346 | if (!isVisible() && attachedData->getControllingProxy() == this){ |
347 | if (d->target->parentItem() == this) { |
348 | d->target->setParentItem(nullptr); |
349 | } else |
350 | qCDebug(lcLayouts) << "Parent was changed to"<< d->target->parentItem() << "while an ItemProxy had control"; |
351 | d->target->setVisible(false); |
352 | attachedData->releaseControl(proxy: this); |
353 | } |
354 | } |
355 | |
356 | /*! \internal |
357 | \brief QQuickLayoutItemProxy::updatePos sets the geometry of the target to |
358 | the geometry of the proxy |
359 | */ |
360 | void QQuickLayoutItemProxy::updatePos() |
361 | { |
362 | if (!isVisible()) |
363 | return; |
364 | if (target()) { |
365 | if (QQuickLayoutItemProxyAttachedData * attachedData = target()->property(name: "QQuickLayoutItemProxyAttachedData").value<QQuickLayoutItemProxyAttachedData*>()) { |
366 | if (attachedData->getControllingProxy() == this) |
367 | geometryChange(newGeom: boundingRect(), oldGeom: boundingRect()); |
368 | } |
369 | } |
370 | } |
371 | |
372 | QQuickLayoutItemProxyPrivate::QQuickLayoutItemProxyPrivate() |
373 | : QQuickItemPrivate(), |
374 | m_expectProxyMinimumWidthChange(false), |
375 | m_expectProxyMinimumHeightChange(false), |
376 | m_expectProxyPreferredWidthChange(false), |
377 | m_expectProxyPreferredHeightChange(false), |
378 | m_expectProxyMaximumWidthChange(false), |
379 | m_expectProxyMaximumHeightChange(false), |
380 | m_expectProxyFillWidthChange(false), |
381 | m_expectProxyFillHeightChange(false), |
382 | m_expectProxyAlignmentChange(false), |
383 | m_expectProxyHorizontalStretchFactorChange(false), |
384 | m_expectProxyVerticalStretchFactorChange(false), |
385 | m_expectProxyMarginsChange(false), |
386 | m_expectProxyLeftMarginChange(false), |
387 | m_expectProxyTopMarginChange(false), |
388 | m_expectProxyRightMarginChange(false), |
389 | m_expectProxyBottomMarginChange(false) |
390 | { |
391 | |
392 | } |
393 | |
394 | /*! \internal |
395 | \class QQuickLayoutItemProxyAttachedData |
396 | \brief Provides attached properties for items that are managed by one or |
397 | more LayoutItemProxy. |
398 | |
399 | It stores all proxies that target the item, and will emit signals when the |
400 | proxies or the controlling proxy changes. Proxies can listen to the signal |
401 | and pick up control if they wish to. |
402 | */ |
403 | QQuickLayoutItemProxyAttachedData::QQuickLayoutItemProxyAttachedData(QObject *parent) |
404 | : QObject(parent), controllingProxy(nullptr) |
405 | { |
406 | |
407 | } |
408 | |
409 | QQuickLayoutItemProxyAttachedData::~QQuickLayoutItemProxyAttachedData() |
410 | { |
411 | // If this is destroyed, so is the target. Clear the target from the |
412 | // proxies so they do not try to access a destroyed object |
413 | for (auto &proxy: std::as_const(t&: proxies)) |
414 | proxy->clearTarget(); |
415 | } |
416 | |
417 | /*! \internal |
418 | \brief QQuickLayoutItemProxyAttachedData::registerProxy registers a proxy |
419 | that manages the item this data is attached to. |
420 | |
421 | This is required to easily notify proxies when the target is destroyed or |
422 | when it is free to take over control. |
423 | */ |
424 | void QQuickLayoutItemProxyAttachedData::registerProxy(QQuickLayoutItemProxy *proxy) |
425 | { |
426 | if (proxies.contains(t: proxy)) |
427 | return; |
428 | |
429 | proxies.append(t: proxy); |
430 | emit proxiesChanged(); |
431 | } |
432 | |
433 | /*! \internal |
434 | \brief QQuickLayoutItemProxyAttachedData::releaseProxy removes a proxy from |
435 | a list of known proxies that manage the item this data is attached to. |
436 | */ |
437 | void QQuickLayoutItemProxyAttachedData::releaseProxy(QQuickLayoutItemProxy *proxy) |
438 | { |
439 | if (proxy == controllingProxy) |
440 | releaseControl(proxy); |
441 | |
442 | proxies.removeAll(t: proxy); |
443 | |
444 | if (proxies.isEmpty()) |
445 | deleteLater(); |
446 | |
447 | emit proxiesChanged(); |
448 | } |
449 | |
450 | /*! \internal |
451 | \brief QQuickLayoutItemProxyAttachedData::takeControl is called by |
452 | LayoutItemProxies when they try to take control over the item this data is |
453 | attached to. |
454 | \return \c true if no other proxy controls the item and if control is |
455 | granted to the proxy, \c false otherwise. |
456 | |
457 | \param proxy The proxy that tries to take control. |
458 | */ |
459 | bool QQuickLayoutItemProxyAttachedData::takeControl(QQuickLayoutItemProxy *proxy) |
460 | { |
461 | if (controllingProxy || !proxies.contains(t: proxy)) |
462 | return false; |
463 | |
464 | qCDebug(lcLayouts) << proxy |
465 | << "takes control of" |
466 | << parent(); |
467 | |
468 | controllingProxy = proxy; |
469 | emit controlTaken(); |
470 | emit controllingProxyChanged(); |
471 | return true; |
472 | } |
473 | |
474 | /*! \internal |
475 | \brief QQuickLayoutItemProxyAttachedData::releaseControl is called by |
476 | LayoutItemProxies when they try no longer control the item |
477 | |
478 | \param proxy The proxy that gives up control. |
479 | */ |
480 | void QQuickLayoutItemProxyAttachedData::releaseControl(QQuickLayoutItemProxy *proxy) |
481 | { |
482 | if (controllingProxy != proxy) |
483 | return; |
484 | |
485 | qCDebug(lcLayouts) << proxy |
486 | << "no longer controls" |
487 | << parent(); |
488 | |
489 | controllingProxy = nullptr; |
490 | emit controlReleased(); |
491 | emit controllingProxyChanged(); |
492 | |
493 | for (auto &otherProxy: std::as_const(t&: proxies)) { |
494 | if (proxy != otherProxy) |
495 | otherProxy->maybeTakeControl(); |
496 | } |
497 | } |
498 | |
499 | /*! \internal |
500 | \brief QQuickLayoutItemProxyAttachedData::getControllingProxy |
501 | \return the proxy that currently controls the item this data is attached to. |
502 | Returns \c null if no proxy controls the item. |
503 | */ |
504 | QQuickLayoutItemProxy *QQuickLayoutItemProxyAttachedData::getControllingProxy() const |
505 | { |
506 | return controllingProxy; |
507 | } |
508 | |
509 | /*! \internal |
510 | \brief QQuickLayoutItemProxyAttachedData::getProxies |
511 | \return a list of all proxies that target the item this data is attached to. |
512 | */ |
513 | QQmlListProperty<QQuickLayoutItemProxy> QQuickLayoutItemProxyAttachedData::getProxies() |
514 | { |
515 | using Type = QQuickLayoutItemProxy; |
516 | using Property = QQmlListProperty<Type>; |
517 | |
518 | return Property( |
519 | this, &proxies, |
520 | [](Property *p) { return static_cast<QList<Type *> *>(p->data)->size(); }, |
521 | [](Property *p, qsizetype i) { return static_cast<QList<Type *> *>(p->data)->at(i); } |
522 | ); |
523 | } |
524 | |
525 | /*! \internal |
526 | \brief QQuickLayoutItemProxyAttachedData::proxyHasControl |
527 | \return \c true if a proxy is controlling the item, \c false otherwise. |
528 | */ |
529 | bool QQuickLayoutItemProxyAttachedData::proxyHasControl() const |
530 | { |
531 | return controllingProxy != nullptr; |
532 | } |
533 |
Definitions
- lcLayouts
- QQuickLayoutItemProxy
- ~QQuickLayoutItemProxy
- geometryChange
- itemChange
- target
- setTarget
- effectiveTarget
- clearTarget
- maybeTakeControl
- updatePos
- QQuickLayoutItemProxyPrivate
- QQuickLayoutItemProxyAttachedData
- ~QQuickLayoutItemProxyAttachedData
- registerProxy
- releaseProxy
- takeControl
- releaseControl
- getControllingProxy
- getProxies
Start learning QML with our Intro Training
Find out more