Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
qquickcontainer.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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
4#include "qquickcontainer_p.h"
6
7#include <QtQuick/private/qquickflickable_p.h>
8
10
15
155{
156 QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(item);
157 if (flickable)
158 return flickable->contentItem();
159 return item;
160}
161
163{
164 Q_Q(QQuickContainer);
168 connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickContainerPrivate::updateContentWidth);
169 connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickContainerPrivate::updateContentHeight);
170}
171
173{
174 Q_Q(QQuickContainer);
175 // ensure correct destruction order (QTBUG-46798)
176 const int count = contentModel->count();
177 for (int i = 0; i < count; ++i) {
179 if (item)
181 }
182
183 if (contentItem) {
185 if (focusItem && window)
187
188 q->contentItemChange(nullptr, contentItem);
190 }
191
194 delete contentModel;
195 contentModel = nullptr;
196}
197
199{
201}
202
204{
205 Q_Q(QQuickContainer);
206 if (!q->isContent(item))
207 return;
209
210 updatingCurrent = true;
211
212 item->setParentItem(effectiveContentItem(q->contentItem()));
214 contentModel->insert(index, item);
215
216 q->itemAdded(index, item);
217
218 int count = contentModel->count();
219 for (int i = index + 1; i < count; ++i)
220 q->itemMoved(i, itemAt(i));
221
222 if (count == 1 && currentIndex == -1)
223 q->setCurrentIndex(index);
224
225 updatingCurrent = false;
226}
227
229{
230 Q_Q(QQuickContainer);
231 int oldCurrent = currentIndex;
232 contentModel->move(from, to);
233
234 updatingCurrent = true;
235
236 q->itemMoved(to, item);
237
238 if (from < to) {
239 for (int i = from; i < to; ++i)
240 q->itemMoved(i, itemAt(i));
241 } else {
242 for (int i = from; i > to; --i)
243 q->itemMoved(i, itemAt(i));
244 }
245
246 if (from == oldCurrent)
247 q->setCurrentIndex(to);
248 else if (from < oldCurrent && to >= oldCurrent)
249 q->setCurrentIndex(oldCurrent - 1);
250 else if (from > oldCurrent && to <= oldCurrent)
251 q->setCurrentIndex(oldCurrent + 1);
252
253 updatingCurrent = false;
254}
255
257{
258 Q_Q(QQuickContainer);
259 if (!q->isContent(item))
260 return;
262
263 updatingCurrent = true;
264
265 int count = contentModel->count();
266 bool currentChanged = false;
267 if (index == currentIndex && (index != 0 || count == 1)) {
268 q->setCurrentIndex(currentIndex - 1);
269 } else if (index < currentIndex) {
270 --currentIndex;
271 currentChanged = true;
272 }
273
275 item->setParentItem(nullptr);
276 contentModel->remove(index);
277 --count;
278
279 q->itemRemoved(index, item);
280
281 for (int i = index; i < count; ++i)
282 q->itemMoved(i, itemAt(i));
283
284 if (currentChanged)
285 emit q->currentIndexChanged();
286
287 updatingCurrent = false;
288}
289
291{
292 Q_Q(QQuickContainer);
293 if (!contentItem)
294 return;
295
297
298 int to = 0;
299 for (int i = 0; i < siblings.size(); ++i) {
300 QQuickItem* sibling = siblings.at(i);
302 continue;
303 int index = contentModel->indexOf(sibling, nullptr);
304 q->moveItem(index, to++);
305 }
306}
307
309{
310 Q_Q(QQuickContainer);
311 if (!updatingCurrent)
312 q->setCurrentIndex(contentItem ? contentItem->property("currentIndex").toInt() : -1);
313}
314
316{
317 // add dynamically reparented items (eg. by a Repeater)
320}
321
323{
324 // remove dynamically unparented items (eg. by a Repeater)
325 if (!parent)
327}
328
330{
332 return;
333
334 // reorder the restacked items (eg. by a Repeater)
335 reorderItems();
336}
337
339{
340 int index = contentModel->indexOf(item, nullptr);
341 if (index != -1)
343 else
345}
346
348{
349 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
352 if (item) {
354 item->setParentItem(effectiveContentItem(q->contentItem()));
355 else if (p->contentModel->indexOf(item, nullptr) == -1)
356 q->addItem(item);
357 } else {
358 p->contentData.append(obj);
359 }
360}
361
363{
364 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
366}
367
369{
370 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
372}
373
375{
376 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
378}
379
381{
382 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
383 q->addItem(item);
384}
385
387{
388 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
390}
391
393{
394 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
395 return q->itemAt(index);
396}
397
399{
400 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
402}
403
405{
406 Q_Q(QQuickContainer);
408 return;
409
411 emit q->contentWidthChanged();
412}
413
415{
416 Q_Q(QQuickContainer);
418 return;
419
421 emit q->contentHeightChanged();
422}
423
426{
427 Q_D(QQuickContainer);
428 d->init();
429}
430
432 : QQuickControl(dd, parent)
433{
434 Q_D(QQuickContainer);
435 d->init();
436}
437
439{
440 Q_D(QQuickContainer);
441 d->cleanup();
442}
443
451{
452 Q_D(const QQuickContainer);
453 return d->contentModel->count();
454}
455
462{
463 Q_D(const QQuickContainer);
464 return d->itemAt(index);
465}
466
473{
474 Q_D(QQuickContainer);
475 insertItem(d->contentModel->count(), item);
476}
477
484{
485 Q_D(QQuickContainer);
486 if (!item)
487 return;
488 const int count = d->contentModel->count();
489 if (index < 0 || index > count)
490 index = count;
491
492 int oldIndex = d->contentModel->indexOf(item, nullptr);
493 if (oldIndex != -1) {
494 if (oldIndex < index)
495 --index;
496 if (oldIndex != index)
497 d->moveItem(oldIndex, index, item);
498 } else {
499 d->insertItem(index, item);
500 }
501}
502
508void QQuickContainer::moveItem(int from, int to)
509{
510 Q_D(QQuickContainer);
511 const int count = d->contentModel->count();
512 if (from < 0 || from > count - 1)
513 return;
514 if (to < 0 || to > count - 1)
515 to = count - 1;
516
517 if (from != to)
518 d->moveItem(from, to, d->itemAt(from));
519}
520
528{
529 Q_D(QQuickContainer);
530 if (!item)
531 return;
532
533 const int index = d->contentModel->indexOf(item, nullptr);
534 if (index == -1)
535 return;
536
537 d->removeItem(index, item);
538 item->deleteLater();
539}
540
549QQuickItem *QQuickContainer::takeItem(int index)
550{
551 Q_D(QQuickContainer);
552 const int count = d->contentModel->count();
553 if (index < 0 || index >= count)
554 return nullptr;
555
557 if (item)
558 d->removeItem(index, item);
559 return item;
560}
561
583{
584 Q_D(const QQuickContainer);
585 return QVariant::fromValue(d->contentModel);
586}
587
604{
605 Q_D(QQuickContainer);
606 if (!d->contentItem)
607 d->executeContentItem();
608 return QQmlListProperty<QObject>(this, nullptr,
613}
614
630{
631 return QQmlListProperty<QQuickItem>(this, nullptr,
636}
637
646{
647 Q_D(const QQuickContainer);
648 return d->currentIndex;
649}
650
662{
663 Q_D(QQuickContainer);
664 if (d->currentIndex == index)
665 return;
666
667 d->currentIndex = index;
670}
671
683void QQuickContainer::incrementCurrentIndex()
684{
685 Q_D(QQuickContainer);
686 if (d->currentIndex < count() - 1)
687 setCurrentIndex(d->currentIndex + 1);
688}
689
701void QQuickContainer::decrementCurrentIndex()
702{
703 Q_D(QQuickContainer);
704 if (d->currentIndex > 0)
705 setCurrentIndex(d->currentIndex - 1);
706}
707
717{
718 Q_D(const QQuickContainer);
719 return itemAt(d->currentIndex);
720}
721
735{
736 Q_D(const QQuickContainer);
737 return d->contentWidth;
738}
739
741{
742 Q_D(QQuickContainer);
743 d->hasContentWidth = true;
744 if (qFuzzyCompare(d->contentWidth, width))
745 return;
746
747 d->contentWidth = width;
748 d->resizeContent();
749 emit contentWidthChanged();
750}
751
753{
754 Q_D(QQuickContainer);
755 if (!d->hasContentWidth)
756 return;
757
758 d->hasContentWidth = false;
759 d->updateContentWidth();
760}
761
775{
776 Q_D(const QQuickContainer);
777 return d->contentHeight;
778}
779
781{
782 Q_D(QQuickContainer);
783 d->hasContentHeight = true;
784 if (qFuzzyCompare(d->contentHeight, height))
785 return;
786
787 d->contentHeight = height;
788 d->resizeContent();
789 emit contentHeightChanged();
790}
791
793{
794 Q_D(QQuickContainer);
795 if (!d->hasContentHeight)
796 return;
797
798 d->hasContentHeight = false;
799 d->updateContentHeight();
800}
801
803{
804 Q_D(QQuickContainer);
806 d->reorderItems();
807}
808
810{
811 Q_D(QQuickContainer);
813 if (change == QQuickItem::ItemChildAddedChange && isComponentComplete() && data.item != d->background && data.item != d->contentItem) {
814 if (!QQuickItemPrivate::get(data.item)->isTransparentForPositioner() && d->contentModel->indexOf(data.item, nullptr) == -1)
815 addItem(data.item);
816 }
817}
818
820{
821 Q_D(QQuickContainer);
822 QQuickControl::contentItemChange(newItem, oldItem);
823
824 static const int slotIndex = metaObject()->indexOfSlot("_q_currentIndexChanged()");
825
826 if (oldItem) {
828 QQuickItem *oldContentItem = effectiveContentItem(oldItem);
829 if (oldContentItem != oldItem)
831
832 int signalIndex = oldItem->metaObject()->indexOfSignal("currentIndexChanged()");
833 if (signalIndex != -1)
834 QMetaObject::disconnect(oldItem, signalIndex, this, slotIndex);
835 }
836
837 if (newItem) {
839 QQuickItem *newContentItem = effectiveContentItem(newItem);
840 if (newContentItem != newItem)
842
843 int signalIndex = newItem->metaObject()->indexOfSignal("currentIndexChanged()");
844 if (signalIndex != -1)
845 QMetaObject::connect(newItem, signalIndex, this, slotIndex);
846 }
847}
848
850{
851 // If the item has a QML context associated to it (it was created in QML),
852 // we add it to the content model. Otherwise, it's probably the default
853 // highlight item that is always created by the item views, which we need
854 // to exclude.
855 //
856 // TODO: Find a better way to identify/exclude the highlight item...
857 return qmlContext(item);
858}
859
861{
863 Q_UNUSED(item);
864}
865
867{
869 Q_UNUSED(item);
870}
871
873{
875 Q_UNUSED(item);
876}
877
879
880#include "moc_qquickcontainer_p.cpp"
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool removeOne(const AT &t)
Definition qlist.h:581
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
T value(qsizetype i) const
Definition qlist.h:661
void append(parameter_type t)
Definition qlist.h:441
void clear()
Definition qlist.h:417
QObject * parent
Definition qobject.h:61
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:298
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4187
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Definition qqmllist.h:24
QObject * object
Definition qqmllist.h:81
void childrenChanged()
int count() const override
\qmlproperty int QtQml.Models::ObjectModel::count
int indexOf(QObject *object, QObject *objectContext) const override
static void contentData_append(QQmlListProperty< QObject > *prop, QObject *obj)
static QQuickItem * contentChildren_at(QQmlListProperty< QQuickItem > *prop, qsizetype index)
void itemChildAdded(QQuickItem *item, QQuickItem *child) override
void itemParentChanged(QQuickItem *item, QQuickItem *parent) override
void moveItem(int from, int to, QQuickItem *item)
static qsizetype contentChildren_count(QQmlListProperty< QQuickItem > *prop)
void itemSiblingOrderChanged(QQuickItem *item) override
static QObject * contentData_at(QQmlListProperty< QObject > *prop, qsizetype index)
void removeItem(int index, QQuickItem *item)
static qsizetype contentData_count(QQmlListProperty< QObject > *prop)
void itemDestroyed(QQuickItem *item) override
static void contentChildren_append(QQmlListProperty< QQuickItem > *prop, QQuickItem *obj)
QQuickItem * itemAt(int index) const
static void contentData_clear(QQmlListProperty< QObject > *prop)
static void contentChildren_clear(QQmlListProperty< QQuickItem > *prop)
void insertItem(int index, QQuickItem *item)
QQmlObjectModel * contentModel
QQuickItemPrivate::ChangeTypes changeTypes
static QQuickContainerPrivate * get(QQuickContainer *container)
QQuickContainer(QQuickItem *parent=nullptr)
virtual void itemMoved(int index, QQuickItem *item)
Q_INVOKABLE void addItem(QQuickItem *item)
\qmlmethod void QtQuick.Controls::Container::addItem(Item item)
void currentItemChanged()
virtual void itemAdded(int index, QQuickItem *item)
QQuickItem * currentItem
Q_INVOKABLE void removeItem(QQuickItem *item)
virtual void itemRemoved(int index, QQuickItem *item)
void setCurrentIndex(int index)
\qmlmethod void QtQuick.Controls::Container::setCurrentIndex(int index)
void setContentWidth(qreal width)
Q_INVOKABLE void moveItem(int from, int to)
\qmlmethod void QtQuick.Controls::Container::moveItem(int from, int to)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
Q_INVOKABLE QQuickItem * itemAt(int index) const
\qmlmethod Item QtQuick.Controls::Container::itemAt(int index)
QQmlListProperty< QQuickItem > contentChildren
\qmlproperty list<Item> QtQuick.Controls::Container::contentChildren
void currentIndexChanged()
virtual bool isContent(QQuickItem *item) const
void contentChildrenChanged()
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override
QQmlListProperty< QObject > contentData
\qmlproperty list<QtObject> QtQuick.Controls::Container::contentData \qmldefault
void setContentHeight(qreal height)
Q_INVOKABLE void insertItem(int index, QQuickItem *item)
\qmlmethod void QtQuick.Controls::Container::insertItem(int index, Item item)
QQuickDeferredPointer< QQuickItem > contentItem
static void hideOldItem(QQuickItem *item)
void itemDestroyed(QQuickItem *item) override
virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void itemChange(ItemChange change, const ItemChangeData &value) override
Called when change occurs for this item.
QQuickItem * contentItem
QPointer< QQuickItem > subFocusItem
void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types)
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
QQuickWindow * window
quint32 componentComplete
static QQuickItemPrivate * get(QQuickItem *item)
bool isTransparentForPositioner() const
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
QList< QQuickItem * > childItems() const
Returns the children of this item.
qreal width
This property holds the width of this item.
Definition qquickitem.h:76
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
qreal height
This property holds the height of this item.
Definition qquickitem.h:77
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:143
@ ItemChildAddedChange
Definition qquickitem.h:144
static QQuickWindowPrivate * get(QQuickWindow *c)
void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason)
\inmodule QtCore
Definition qvariant.h:64
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
auto signalIndex
Combined button and popup list for selecting options.
@ OtherFocusReason
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
GLint GLsizei GLsizei height
GLuint index
[2]
GLenum GLenum GLsizei count
GLint GLsizei width
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLhandleARB obj
[2]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:71
static QT_BEGIN_NAMESPACE QQuickItem * effectiveContentItem(QQuickItem *item)
Abstract base type providing functionality common to containers.
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:483
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:70
double qreal
Definition qtypes.h:92
obj metaObject() -> className()
QGraphicsItem * item
QLayoutItem * child
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:44
static bool disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index)
Definition qobject.cpp:3504
static Connection connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=nullptr)
Definition qobject.cpp:3419
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
\inmodule QtQuick
Definition qquickitem.h:158