8#include <QtQuick/private/qquickflickable_p.h>
9#include <QtQuick/private/qquickitemview_p.h>
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
158 QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(item);
160 return flickable->contentItem();
164void QQuickContainerPrivate::init()
166 Q_Q(QQuickContainer);
167 contentModel =
new QQmlObjectModel(q);
168 QObject::connect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
169 QObject::connect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
170 connect(q, &QQuickControl::implicitContentWidthChanged,
this, &QQuickContainerPrivate::updateContentWidth);
171 connect(q, &QQuickControl::implicitContentHeightChanged,
this, &QQuickContainerPrivate::updateContentHeight);
172 setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Preferred);
175void QQuickContainerPrivate::cleanup()
177 Q_Q(QQuickContainer);
179 const int count = contentModel->count();
180 for (
int i = 0; i < count; ++i) {
181 QQuickItem *item = itemAt(i);
183 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
187 QQuickItem *focusItem = QQuickItemPrivate::get(contentItem)->subFocusItem;
188 if (focusItem && window)
189 deliveryAgentPrivate()->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason);
191 q->contentItemChange(
nullptr, contentItem);
192 QQuickControlPrivate::hideOldItem(contentItem);
195 QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
196 QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
198 contentModel =
nullptr;
201QQuickItem *QQuickContainerPrivate::itemAt(
int index)
const
203 return qobject_cast<QQuickItem *>(contentModel->get(index));
206void QQuickContainerPrivate::insertItem(
int index, QQuickItem *item)
208 Q_Q(QQuickContainer);
209 if (!q->isContent(item))
211 contentData.append(item);
213 updatingCurrent =
true;
215 item->setParentItem(effectiveContentItem(q->contentItem()));
217 QQuickItemPrivate::get(item)->addItemChangeListener(
this, changeTypes);
218 contentModel->insert(index, item);
220 q->itemAdded(index, item);
222 int count = contentModel->count();
223 for (
int i = index + 1; i < count; ++i)
224 q->itemMoved(i, itemAt(i));
226 if (count == 1 && currentIndex == -1)
227 q->setCurrentIndex(index);
229 updatingCurrent =
false;
232void QQuickContainerPrivate::moveItem(
int from,
int to, QQuickItem *item)
234 Q_Q(QQuickContainer);
235 int oldCurrent = currentIndex;
236 contentModel->move(from, to);
238 updatingCurrent =
true;
240 q->itemMoved(to, item);
243 for (
int i = from; i < to; ++i)
244 q->itemMoved(i, itemAt(i));
246 for (
int i = from; i > to; --i)
247 q->itemMoved(i, itemAt(i));
250 if (from == oldCurrent)
251 q->setCurrentIndex(to);
252 else if (from < oldCurrent && to >= oldCurrent)
253 q->setCurrentIndex(oldCurrent - 1);
254 else if (from > oldCurrent && to <= oldCurrent)
255 q->setCurrentIndex(oldCurrent + 1);
257 updatingCurrent =
false;
260void QQuickContainerPrivate::removeItem(
int index, QQuickItem *item)
262 Q_Q(QQuickContainer);
263 const bool item_inDestructor = QQuickItemPrivate::get(item)->inDestructor;
264 if (!item_inDestructor && !q->isContent(item))
266 contentData.removeOne(item);
268 updatingCurrent =
true;
270 int count = contentModel->count();
271 bool currentChanged =
false;
272 if (index == currentIndex && (index != 0 || count == 1)) {
273 q->setCurrentIndex(currentIndex - 1);
274 }
else if (index < currentIndex) {
276 currentChanged =
true;
279 if (!item_inDestructor) {
281 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, changeTypes);
282 item->setParentItem(
nullptr);
284 contentModel->remove(index);
287 q->itemRemoved(index, item);
289 for (
int i = index; i < count; ++i)
290 q->itemMoved(i, itemAt(i));
293 emit q->currentIndexChanged();
295 updatingCurrent =
false;
298void QQuickContainerPrivate::reorderItems()
300 Q_Q(QQuickContainer);
311 bool allowReorder =
true;
312 if (!qobject_cast<QQuickFlickable *>(contentItem)) {
313 for (
int index = 0; index < contentModel->count(); index++) {
314 if (
const auto *item = qobject_cast<QQuickItem *>(contentModel->get(index))) {
315 const auto *parentItem = item->parentItem();
316 if (parentItem && !qobject_cast<QQuickItemView *>(parentItem->parentItem())) {
317 allowReorder =
false;
325 QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems();
327 for (
int i = 0; i < siblings.size(); ++i) {
328 QQuickItem* sibling = siblings.at(i);
329 if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner())
331 const int index = contentModel->indexOf(sibling,
nullptr);
333 q->moveItem(index, to++);
338void QQuickContainerPrivate::maybeCullItem(QQuickItem *item)
340 if (QQuickItemPrivate::get(item)->isTransparentForPositioner())
348 if (!qobject_cast<QQuickItemView *>(contentItem))
353 const bool hasZeroSize = qFuzzyIsNull(width) && qFuzzyIsNull(height);
357 QQuickItemPrivate::get(item)->setCulled(
true);
360void QQuickContainerPrivate::maybeCullItems()
365 const QList<QQuickItem *> childItems = effectiveContentItem(contentItem)->childItems();
366 for (
auto &childItem : childItems)
367 maybeCullItem(childItem);
370void QQuickContainerPrivate::_q_currentIndexChanged()
372 Q_Q(QQuickContainer);
373 if (!updatingCurrent)
374 q->setCurrentIndex(contentItem ? contentItem->property(
"currentIndex").toInt() : -1);
377void QQuickContainerPrivate::itemChildAdded(QQuickItem *, QQuickItem *child)
380 if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child))
381 insertItem(contentModel->count(), child);
384void QQuickContainerPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
388 removeItem(contentModel->indexOf(item,
nullptr), item);
391void QQuickContainerPrivate::itemSiblingOrderChanged(QQuickItem *)
393 if (!componentComplete)
400void QQuickContainerPrivate::itemDestroyed(QQuickItem *item)
402 int index = contentModel->indexOf(item,
nullptr);
404 removeItem(index, item);
406 QQuickControlPrivate::itemDestroyed(item);
409void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
411 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
412 QQuickContainerPrivate *p = QQuickContainerPrivate::get(q);
413 QQuickItem *item = qobject_cast<QQuickItem *>(obj);
415 if (QQuickItemPrivate::get(item)->isTransparentForPositioner())
416 item->setParentItem(effectiveContentItem(q->contentItem()));
417 else if (p->contentModel->indexOf(item,
nullptr) == -1)
420 p->contentData.append(obj);
424qsizetype QQuickContainerPrivate::contentData_count(QQmlListProperty<QObject> *prop)
426 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
427 return QQuickContainerPrivate::get(q)->contentData.size();
430QObject *QQuickContainerPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index)
432 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
433 return QQuickContainerPrivate::get(q)->contentData.value(index);
436void QQuickContainerPrivate::contentData_clear(QQmlListProperty<QObject> *prop)
438 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
439 return QQuickContainerPrivate::get(q)->contentData.clear();
442void QQuickContainerPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item)
444 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
448qsizetype QQuickContainerPrivate::contentChildren_count(QQmlListProperty<QQuickItem> *prop)
450 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
451 return QQuickContainerPrivate::get(q)->contentModel->count();
454QQuickItem *QQuickContainerPrivate::contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index)
456 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
457 return q->itemAt(index);
460void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop)
462 QQuickContainer *q =
static_cast<QQuickContainer *>(prop->object);
463 return QQuickContainerPrivate::get(q)->contentModel->clear();
466void QQuickContainerPrivate::updateContentWidth()
468 Q_Q(QQuickContainer);
469 if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
472 contentWidth = implicitContentWidth;
473 emit q->contentWidthChanged();
476void QQuickContainerPrivate::updateContentHeight()
478 Q_Q(QQuickContainer);
479 if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
482 contentHeight = implicitContentHeight;
483 emit q->contentHeightChanged();
486QQuickContainer::QQuickContainer(QQuickItem *parent)
487 : QQuickControl(*(
new QQuickContainerPrivate), parent)
489 Q_D(QQuickContainer);
493QQuickContainer::QQuickContainer(QQuickContainerPrivate &dd, QQuickItem *parent)
494 : QQuickControl(dd, parent)
496 Q_D(QQuickContainer);
500QQuickContainer::~QQuickContainer()
502 Q_D(QQuickContainer);
507
508
509
510
511
512int QQuickContainer::count()
const
514 Q_D(
const QQuickContainer);
515 return d->contentModel->count();
519
520
521
522
523QQuickItem *QQuickContainer::itemAt(
int index)
const
525 Q_D(
const QQuickContainer);
526 return d->itemAt(index);
530
531
532
533
534void QQuickContainer::addItem(QQuickItem *item)
536 Q_D(QQuickContainer);
537 insertItem(d->contentModel->count(), item);
541
542
543
544
545void QQuickContainer::insertItem(
int index, QQuickItem *item)
547 Q_D(QQuickContainer);
550 const int count = d->contentModel->count();
551 if (index < 0 || index > count)
554 int oldIndex = d->contentModel->indexOf(item,
nullptr);
555 if (oldIndex != -1) {
556 if (oldIndex < index)
558 if (oldIndex != index)
559 d->moveItem(oldIndex, index, item);
561 d->insertItem(index, item);
566
567
568
569
570void QQuickContainer::moveItem(
int from,
int to)
572 Q_D(QQuickContainer);
573 const int count = d->contentModel->count();
574 if (from < 0 || from > count - 1)
576 if (to < 0 || to > count - 1)
580 d->moveItem(from, to, d->itemAt(from));
584
585
586
587
588
589void QQuickContainer::removeItem(QQuickItem *item)
591 Q_D(QQuickContainer);
595 const int index = d->contentModel->indexOf(item,
nullptr);
599 d->removeItem(index, item);
604
605
606
607
608
609
610
611QQuickItem *QQuickContainer::takeItem(
int index)
613 Q_D(QQuickContainer);
614 const int count = d->contentModel->count();
615 if (index < 0 || index >= count)
618 QQuickItem *item = itemAt(index);
620 d->removeItem(index, item);
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644QVariant QQuickContainer::contentModel()
const
646 Q_D(
const QQuickContainer);
647 return QVariant::fromValue(d->contentModel);
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665QQmlListProperty<QObject> QQuickContainer::contentData()
667 Q_D(QQuickContainer);
669 d->executeContentItem();
670 return QQmlListProperty<QObject>(
this,
nullptr,
671 QQuickContainerPrivate::contentData_append,
672 QQuickContainerPrivate::contentData_count,
673 QQuickContainerPrivate::contentData_at,
674 QQuickContainerPrivate::contentData_clear);
678
679
680
681
682
683
684
685
686
687
688
689
690
691QQmlListProperty<QQuickItem> QQuickContainer::contentChildren()
693 return QQmlListProperty<QQuickItem>(
this,
nullptr,
694 QQuickContainerPrivate::contentChildren_append,
695 QQuickContainerPrivate::contentChildren_count,
696 QQuickContainerPrivate::contentChildren_at,
697 QQuickContainerPrivate::contentChildren_clear);
701
702
703
704
705
706
707int QQuickContainer::currentIndex()
const
709 Q_D(
const QQuickContainer);
710 return d->currentIndex;
714
715
716
717
718
719
720
721
722
723void QQuickContainer::setCurrentIndex(
int index)
725 Q_D(QQuickContainer);
726 if (d->currentIndex == index)
729 d->currentIndex = index;
730 emit currentIndexChanged();
731 emit currentItemChanged();
735
736
737
738
739
740
741
742
743
744
745void QQuickContainer::incrementCurrentIndex()
747 Q_D(QQuickContainer);
748 if (d->currentIndex < count() - 1)
749 setCurrentIndex(d->currentIndex + 1);
753
754
755
756
757
758
759
760
761
762
763void QQuickContainer::decrementCurrentIndex()
765 Q_D(QQuickContainer);
766 if (d->currentIndex > 0)
767 setCurrentIndex(d->currentIndex - 1);
771
772
773
774
775
776
777
778QQuickItem *QQuickContainer::currentItem()
const
780 Q_D(
const QQuickContainer);
781 return itemAt(d->currentIndex);
785
786
787
788
789
790
791
792
793
794
795
796qreal QQuickContainer::contentWidth()
const
798 Q_D(
const QQuickContainer);
799 return d->contentWidth;
802void QQuickContainer::setContentWidth(qreal width)
804 Q_D(QQuickContainer);
805 d->hasContentWidth =
true;
806 if (qFuzzyCompare(d->contentWidth, width))
809 d->contentWidth = width;
811 d->updateImplicitContentWidth();
812 emit contentWidthChanged();
815void QQuickContainer::resetContentWidth()
817 Q_D(QQuickContainer);
818 if (!d->hasContentWidth)
821 d->hasContentWidth =
false;
822 d->updateImplicitContentWidth();
826
827
828
829
830
831
832
833
834
835
836
837qreal QQuickContainer::contentHeight()
const
839 Q_D(
const QQuickContainer);
840 return d->contentHeight;
843void QQuickContainer::setContentHeight(qreal height)
845 Q_D(QQuickContainer);
846 d->hasContentHeight =
true;
847 if (qFuzzyCompare(d->contentHeight, height))
850 d->contentHeight = height;
852 d->updateImplicitContentHeight();
853 emit contentHeightChanged();
856void QQuickContainer::resetContentHeight()
858 Q_D(QQuickContainer);
859 if (!d->hasContentHeight)
862 d->hasContentHeight =
false;
863 d->updateImplicitContentHeight();
866qreal QQuickContainerPrivate::getContentWidth()
const
871 return QQuickControlPrivate::getContentWidth();
874qreal QQuickContainerPrivate::getContentHeight()
const
876 if (hasContentHeight)
877 return contentHeight;
879 return QQuickControlPrivate::getContentHeight();
882void QQuickContainer::componentComplete()
884 Q_D(QQuickContainer);
885 QQuickControl::componentComplete();
890void QQuickContainer::itemChange(ItemChange change,
const ItemChangeData &data)
892 Q_D(QQuickContainer);
893 QQuickControl::itemChange(change, data);
894 if (change == QQuickItem::ItemChildAddedChange && isComponentComplete() && data.item != d->background && data.item != d->contentItem) {
895 if (!QQuickItemPrivate::get(data.item)->isTransparentForPositioner() && d->contentModel->indexOf(data.item,
nullptr) == -1)
900void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
902 Q_D(QQuickContainer);
903 QQuickControl::contentItemChange(newItem, oldItem);
905 static const int slotIndex = metaObject()->indexOfSlot(
"_q_currentIndexChanged()");
908 QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
909 QQuickItem *oldContentItem = effectiveContentItem(oldItem);
910 if (oldContentItem != oldItem)
911 QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children);
913 int signalIndex = oldItem->metaObject()->indexOfSignal(
"currentIndexChanged()");
914 if (signalIndex != -1)
915 QMetaObject::disconnect(oldItem, signalIndex,
this, slotIndex);
919 QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
920 QQuickItem *newContentItem = effectiveContentItem(newItem);
921 if (newContentItem != newItem)
922 QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children);
924 int signalIndex = newItem->metaObject()->indexOfSignal(
"currentIndexChanged()");
925 if (signalIndex != -1)
926 QMetaObject::connect(newItem, signalIndex,
this, slotIndex);
930bool QQuickContainer::isContent(QQuickItem *item)
const
938 return qmlContext(item);
941void QQuickContainer::itemAdded(
int index, QQuickItem *item)
947void QQuickContainer::itemMoved(
int index, QQuickItem *item)
953void QQuickContainer::itemRemoved(
int index, QQuickItem *item)
961#include "moc_qquickcontainer_p.cpp"
static QT_BEGIN_NAMESPACE QQuickItem * effectiveContentItem(QQuickItem *item)
Abstract base type providing functionality common to containers.