diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-10-21 14:58:38 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-10-22 14:42:22 +0000 |
commit | 8652098027b59edaf51f1779a7d575da931061c7 (patch) | |
tree | a742a9f82a167f5de98e9ac54263a7ea0f7b4d5a /src/templates/qquickcontainer.cpp | |
parent | e3bf4f771458590dd003fc710803c1c1babea68e (diff) |
Move the internal ExclusiveGroup from TabBar to Container
TabBar needs to support PathView as a content item (for the Universal
style). PathView creates a highlight item, which wrongly ends up being
added as a content child. It shows up as an extra empty TabBar item, and
leads to a warning from ExclusiveGroup::addCheckable().
An exclusive group instance is lazily created only for those containers
that need it. This allows us to simplify the virtual hooks for added and
removed items, whereas otherwise we would had had to add more complex
hooks (before _and_ after adding an item) to be able to control/ignore
the highlight somehow from the TabBar subclass.
Change-Id: I2c35a1dd80541bc6b30e713a760277940a5486ed
Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src/templates/qquickcontainer.cpp')
-rw-r--r-- | src/templates/qquickcontainer.cpp | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/src/templates/qquickcontainer.cpp b/src/templates/qquickcontainer.cpp index 945d1c32..46c3f707 100644 --- a/src/templates/qquickcontainer.cpp +++ b/src/templates/qquickcontainer.cpp @@ -36,6 +36,7 @@ #include "qquickcontainer_p.h" #include "qquickcontainer_p_p.h" +#include "qquickexclusivegroup_p.h" QT_BEGIN_NAMESPACE @@ -52,7 +53,7 @@ QT_BEGIN_NAMESPACE \sa {Container Controls} */ -QQuickContainerPrivate::QQuickContainerPrivate() : contentModel(Q_NULLPTR), currentIndex(-1), updatingCurrent(false) +QQuickContainerPrivate::QQuickContainerPrivate() : contentModel(Q_NULLPTR), currentIndex(-1), updatingCurrent(false), exclusiveGroup(Q_NULLPTR) { } @@ -86,9 +87,14 @@ QQuickItem *QQuickContainerPrivate::itemAt(int index) const void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) { - QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); contentData.append(item); + if (exclusiveGroup && !exclusiveGroup->isCheckable(item)) + return; + + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); contentModel->insert(index, item); + if (exclusiveGroup) + exclusiveGroup->addCheckable(item); itemInserted(index, item); @@ -112,17 +118,25 @@ void QQuickContainerPrivate::itemMoved(int from, int to) { Q_Q(QQuickContainer); updatingCurrent = true; - if (from == currentIndex) - q->setCurrentIndex(to); - else if (from < currentIndex && to >= currentIndex) - q->setCurrentIndex(currentIndex - 1); - else if (from > currentIndex && to <= currentIndex) - q->setCurrentIndex(currentIndex + 1); + if (exclusiveGroup) { + q->setCurrentIndex(contentModel->indexOf(exclusiveGroup->current(), Q_NULLPTR)); + } else { + if (from == currentIndex) + q->setCurrentIndex(to); + else if (from < currentIndex && to >= currentIndex) + q->setCurrentIndex(currentIndex - 1); + else if (from > currentIndex && to <= currentIndex) + q->setCurrentIndex(currentIndex + 1); + } updatingCurrent = false; } void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) { + contentData.removeOne(item); + if (exclusiveGroup && !exclusiveGroup->isCheckable(item)) + return; + Q_Q(QQuickContainer); bool currentChanged = false; if (index == currentIndex) { @@ -134,8 +148,9 @@ void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); item->setParentItem(Q_NULLPTR); - contentData.removeOne(item); contentModel->remove(index); + if (exclusiveGroup) + exclusiveGroup->removeCheckable(item); itemRemoved(item); @@ -147,6 +162,13 @@ void QQuickContainerPrivate::itemRemoved(QQuickItem *) { } +void QQuickContainerPrivate::_q_currentItemChanged() +{ + Q_Q(QQuickContainer); + if (!updatingCurrent) + q->setCurrentIndex(contentModel->indexOf(exclusiveGroup->current(), Q_NULLPTR)); +} + void QQuickContainerPrivate::_q_currentIndexChanged() { Q_Q(QQuickContainer); @@ -427,6 +449,8 @@ void QQuickContainer::setCurrentIndex(int index) d->currentIndex = index; emit currentIndexChanged(); emit currentItemChanged(); + if (d->exclusiveGroup && isComponentComplete()) + d->exclusiveGroup->setCurrent(d->contentModel->get(index)); } } @@ -441,6 +465,48 @@ QQuickItem *QQuickContainer::currentItem() const return itemAt(d->currentIndex); } +/*! + \qmlproperty bool Qt.labs.controls::Container::exclusive + + This property holds whether the container is considered exclusive. + An exclusive container manages the the content children with an + ExclusiveGroup. + + The default value is \c false. + + \sa ExclusiveGroup +*/ +bool QQuickContainer::isExclusive() const +{ + Q_D(const QQuickContainer); + return d->exclusiveGroup; +} + +void QQuickContainer::setExclusive(bool exclusive) +{ + Q_D(QQuickContainer); + if (exclusive == isExclusive()) + return; + + if (exclusive) { + if (!d->exclusiveGroup) { + d->exclusiveGroup = new QQuickExclusiveGroup(this); + connect(d->exclusiveGroup, &QQuickExclusiveGroup::currentChanged, this, &QQuickContainer::currentItemChanged); + QObjectPrivate::connect(d->exclusiveGroup, &QQuickExclusiveGroup::currentChanged, d, &QQuickContainerPrivate::_q_currentItemChanged); + + const int count = d->contentModel->count(); + for (int i = 0; i < count; ++i) { + QObject *object = d->contentModel->get(i); + if (d->exclusiveGroup->isCheckable(object)) + d->exclusiveGroup->addCheckable(object); + } + } + } else { + delete d->exclusiveGroup; + d->exclusiveGroup = Q_NULLPTR; + } +} + void QQuickContainer::itemChange(ItemChange change, const ItemChangeData &data) { Q_D(QQuickContainer); |