Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
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
172
174{
175 Q_Q(QQuickContainer);
176 // ensure correct destruction order (QTBUG-46798)
177 const int count = contentModel->count();
178 for (int i = 0; i < count; ++i) {
180 if (item)
181 QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes);
182 }
183
184 if (contentItem) {
185 QQuickItem *focusItem = QQuickItemPrivate::get(contentItem)->subFocusItem;
186 if (focusItem && window)
187 QQuickWindowPrivate::get(window)->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason);
188
189 q->contentItemChange(nullptr, contentItem);
191 }
192
195 delete contentModel;
196 contentModel = nullptr;
197}
198
203
205{
206 Q_Q(QQuickContainer);
207 if (!q->isContent(item))
208 return;
210
211 updatingCurrent = true;
212
213 item->setParentItem(effectiveContentItem(q->contentItem()));
214 QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes);
215 contentModel->insert(index, item);
216
217 q->itemAdded(index, item);
218
219 int count = contentModel->count();
220 for (int i = index + 1; i < count; ++i)
221 q->itemMoved(i, itemAt(i));
222
223 if (count == 1 && currentIndex == -1)
224 q->setCurrentIndex(index);
225
226 updatingCurrent = false;
227}
228
230{
231 Q_Q(QQuickContainer);
232 int oldCurrent = currentIndex;
233 contentModel->move(from, to);
234
235 updatingCurrent = true;
236
237 q->itemMoved(to, item);
238
239 if (from < to) {
240 for (int i = from; i < to; ++i)
241 q->itemMoved(i, itemAt(i));
242 } else {
243 for (int i = from; i > to; --i)
244 q->itemMoved(i, itemAt(i));
245 }
246
247 if (from == oldCurrent)
248 q->setCurrentIndex(to);
249 else if (from < oldCurrent && to >= oldCurrent)
250 q->setCurrentIndex(oldCurrent - 1);
251 else if (from > oldCurrent && to <= oldCurrent)
252 q->setCurrentIndex(oldCurrent + 1);
253
254 updatingCurrent = false;
255}
256
258{
259 Q_Q(QQuickContainer);
260 const bool item_inDestructor = QQuickItemPrivate::get(item)->inDestructor;
261 if (!item_inDestructor && !q->isContent(item))
262 return;
264
265 updatingCurrent = true;
266
267 int count = contentModel->count();
268 bool currentChanged = false;
269 if (index == currentIndex && (index != 0 || count == 1)) {
270 q->setCurrentIndex(currentIndex - 1);
271 } else if (index < currentIndex) {
272 --currentIndex;
273 currentChanged = true;
274 }
275
276 if (!item_inDestructor) {
277 // already handled by ~QQuickItem
278 QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes);
279 item->setParentItem(nullptr);
280 }
281 contentModel->remove(index);
282 --count;
283
284 q->itemRemoved(index, item);
285
286 for (int i = index; i < count; ++i)
287 q->itemMoved(i, itemAt(i));
288
289 if (currentChanged)
290 emit q->currentIndexChanged();
291
292 updatingCurrent = false;
293}
294
296{
297 Q_Q(QQuickContainer);
298 if (!contentItem)
299 return;
300
301 QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems();
302
303 int to = 0;
304 for (int i = 0; i < siblings.size(); ++i) {
305 QQuickItem* sibling = siblings.at(i);
307 continue;
308 int index = contentModel->indexOf(sibling, nullptr);
309 q->moveItem(index, to++);
310 }
311}
312
314{
315 Q_Q(QQuickContainer);
316 if (!updatingCurrent)
317 q->setCurrentIndex(contentItem ? contentItem->property("currentIndex").toInt() : -1);
318}
319
321{
322 // add dynamically reparented items (eg. by a Repeater)
325}
326
328{
329 // remove dynamically unparented items (eg. by a Repeater)
330 if (!parent)
332}
333
335{
337 return;
338
339 // reorder the restacked items (eg. by a Repeater)
340 reorderItems();
341}
342
351
352void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
353{
354 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
357 if (item) {
359 item->setParentItem(effectiveContentItem(q->contentItem()));
360 else if (p->contentModel->indexOf(item, nullptr) == -1)
361 q->addItem(item);
362 } else {
363 p->contentData.append(obj);
364 }
365}
366
368{
369 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
370 return QQuickContainerPrivate::get(q)->contentData.size();
371}
372
374{
375 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
376 return QQuickContainerPrivate::get(q)->contentData.value(index);
377}
378
379void QQuickContainerPrivate::contentData_clear(QQmlListProperty<QObject> *prop)
380{
381 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
382 return QQuickContainerPrivate::get(q)->contentData.clear();
383}
384
385void QQuickContainerPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item)
386{
387 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
388 q->addItem(item);
389}
390
392{
393 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
394 return QQuickContainerPrivate::get(q)->contentModel->count();
395}
396
398{
399 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
400 return q->itemAt(index);
401}
402
403void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop)
404{
405 QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
406 return QQuickContainerPrivate::get(q)->contentModel->clear();
407}
408
418
428
430 : QQuickControl(*(new QQuickContainerPrivate), parent)
431{
432 Q_D(QQuickContainer);
433 d->init();
434}
435
437 : QQuickControl(dd, parent)
438{
439 Q_D(QQuickContainer);
440 d->init();
441}
442
444{
445 Q_D(QQuickContainer);
446 d->cleanup();
447}
448
456{
457 Q_D(const QQuickContainer);
458 return d->contentModel->count();
459}
460
467{
468 Q_D(const QQuickContainer);
469 return d->itemAt(index);
470}
471
478{
479 Q_D(QQuickContainer);
480 insertItem(d->contentModel->count(), item);
481}
482
489{
490 Q_D(QQuickContainer);
491 if (!item)
492 return;
493 const int count = d->contentModel->count();
494 if (index < 0 || index > count)
495 index = count;
496
497 int oldIndex = d->contentModel->indexOf(item, nullptr);
498 if (oldIndex != -1) {
499 if (oldIndex < index)
500 --index;
501 if (oldIndex != index)
502 d->moveItem(oldIndex, index, item);
503 } else {
504 d->insertItem(index, item);
505 }
506}
507
513void QQuickContainer::moveItem(int from, int to)
514{
515 Q_D(QQuickContainer);
516 const int count = d->contentModel->count();
517 if (from < 0 || from > count - 1)
518 return;
519 if (to < 0 || to > count - 1)
520 to = count - 1;
521
522 if (from != to)
523 d->moveItem(from, to, d->itemAt(from));
524}
525
533{
534 Q_D(QQuickContainer);
535 if (!item)
536 return;
537
538 const int index = d->contentModel->indexOf(item, nullptr);
539 if (index == -1)
540 return;
541
542 d->removeItem(index, item);
543 item->deleteLater();
544}
545
554QQuickItem *QQuickContainer::takeItem(int index)
555{
556 Q_D(QQuickContainer);
557 const int count = d->contentModel->count();
558 if (index < 0 || index >= count)
559 return nullptr;
560
562 if (item)
563 d->removeItem(index, item);
564 return item;
565}
566
588{
589 Q_D(const QQuickContainer);
590 return QVariant::fromValue(d->contentModel);
591}
592
608QQmlListProperty<QObject> QQuickContainer::contentData()
609{
610 Q_D(QQuickContainer);
611 if (!d->contentItem)
612 d->executeContentItem();
613 return QQmlListProperty<QObject>(this, nullptr,
618}
619
634QQmlListProperty<QQuickItem> QQuickContainer::contentChildren()
635{
636 return QQmlListProperty<QQuickItem>(this, nullptr,
641}
642
651{
652 Q_D(const QQuickContainer);
653 return d->currentIndex;
654}
655
667{
668 Q_D(QQuickContainer);
669 if (d->currentIndex == index)
670 return;
671
672 d->currentIndex = index;
675}
676
688void QQuickContainer::incrementCurrentIndex()
689{
690 Q_D(QQuickContainer);
691 if (d->currentIndex < count() - 1)
692 setCurrentIndex(d->currentIndex + 1);
693}
694
706void QQuickContainer::decrementCurrentIndex()
707{
708 Q_D(QQuickContainer);
709 if (d->currentIndex > 0)
710 setCurrentIndex(d->currentIndex - 1);
711}
712
722{
723 Q_D(const QQuickContainer);
724 return itemAt(d->currentIndex);
725}
726
740{
741 Q_D(const QQuickContainer);
742 return d->contentWidth;
743}
744
746{
747 Q_D(QQuickContainer);
748 d->hasContentWidth = true;
749 if (qFuzzyCompare(d->contentWidth, width))
750 return;
751
752 d->contentWidth = width;
753 d->resizeContent();
754 emit contentWidthChanged();
755}
756
758{
759 Q_D(QQuickContainer);
760 if (!d->hasContentWidth)
761 return;
762
763 d->hasContentWidth = false;
764 d->updateContentWidth();
765}
766
780{
781 Q_D(const QQuickContainer);
782 return d->contentHeight;
783}
784
786{
787 Q_D(QQuickContainer);
788 d->hasContentHeight = true;
789 if (qFuzzyCompare(d->contentHeight, height))
790 return;
791
792 d->contentHeight = height;
793 d->resizeContent();
794 emit contentHeightChanged();
795}
796
798{
799 Q_D(QQuickContainer);
800 if (!d->hasContentHeight)
801 return;
802
803 d->hasContentHeight = false;
804 d->updateContentHeight();
805}
806
808{
809 Q_D(QQuickContainer);
811 d->reorderItems();
812}
813
815{
816 Q_D(QQuickContainer);
818 if (change == QQuickItem::ItemChildAddedChange && isComponentComplete() && data.item != d->background && data.item != d->contentItem) {
819 if (!QQuickItemPrivate::get(data.item)->isTransparentForPositioner() && d->contentModel->indexOf(data.item, nullptr) == -1)
820 addItem(data.item);
821 }
822}
823
825{
826 Q_D(QQuickContainer);
827 QQuickControl::contentItemChange(newItem, oldItem);
828
829 static const int slotIndex = metaObject()->indexOfSlot("_q_currentIndexChanged()");
830
831 if (oldItem) {
833 QQuickItem *oldContentItem = effectiveContentItem(oldItem);
834 if (oldContentItem != oldItem)
835 QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children);
836
837 int signalIndex = oldItem->metaObject()->indexOfSignal("currentIndexChanged()");
838 if (signalIndex != -1)
839 QMetaObject::disconnect(oldItem, signalIndex, this, slotIndex);
840 }
841
842 if (newItem) {
844 QQuickItem *newContentItem = effectiveContentItem(newItem);
845 if (newContentItem != newItem)
846 QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children);
847
848 int signalIndex = newItem->metaObject()->indexOfSignal("currentIndexChanged()");
849 if (signalIndex != -1)
850 QMetaObject::connect(newItem, signalIndex, this, slotIndex);
851 }
852}
853
855{
856 // If the item has a QML context associated to it (it was created in QML),
857 // we add it to the content model. Otherwise, it's probably the default
858 // highlight item that is always created by the item views, which we need
859 // to exclude.
860 //
861 // TODO: Find a better way to identify/exclude the highlight item...
862 return qmlContext(item);
863}
864
870
876
882
884
885#include "moc_qquickcontainer_p.cpp"
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
static constexpr Policy Preferred
bool removeOne(const AT &t)
Definition qlist.h:598
void append(parameter_type t)
Definition qlist.h:458
QObject * parent
Definition qobject.h:73
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:299
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4323
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
void setSizePolicy(const QLayoutPolicy::Policy &horizontalPolicy, const QLayoutPolicy::Policy &verticalPolicy)
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:63
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
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:76
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:144
@ ItemChildAddedChange
Definition qquickitem.h:145
static QQuickWindowPrivate * get(QQuickWindow *c)
\inmodule QtCore
Definition qvariant.h:65
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:536
auto signalIndex
Combined button and popup list for selecting options.
@ OtherFocusReason
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
GLint GLsizei GLsizei height
GLuint index
[2]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei width
GLhandleARB obj
[2]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
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:492
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
double qreal
Definition qtypes.h:187
obj metaObject() -> className()
QGraphicsItem * item
QLayoutItem * child
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:45
static bool disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index)
Definition qobject.cpp:3641
static Connection connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=nullptr)
Definition qobject.cpp:3556
\inmodule QtQuick
Definition qquickitem.h:159