aboutsummaryrefslogtreecommitdiffstats
path: root/src/templates
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-21 14:58:38 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-22 14:42:22 +0000
commit8652098027b59edaf51f1779a7d575da931061c7 (patch)
treea742a9f82a167f5de98e9ac54263a7ea0f7b4d5a /src/templates
parente3bf4f771458590dd003fc710803c1c1babea68e (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')
-rw-r--r--src/templates/qquickcontainer.cpp84
-rw-r--r--src/templates/qquickcontainer_p.h6
-rw-r--r--src/templates/qquickcontainer_p_p.h4
-rw-r--r--src/templates/qquicktabbar.cpp48
4 files changed, 87 insertions, 55 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);
diff --git a/src/templates/qquickcontainer_p.h b/src/templates/qquickcontainer_p.h
index 52bc631c..2ce573b1 100644
--- a/src/templates/qquickcontainer_p.h
+++ b/src/templates/qquickcontainer_p.h
@@ -64,6 +64,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickContainer : public QQuickControl
Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL)
Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL)
+ Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive NOTIFY exclusiveChanged FINAL)
Q_CLASSINFO("DefaultProperty", "contentData")
public:
@@ -84,6 +85,9 @@ public:
int currentIndex() const;
QQuickItem *currentItem() const;
+ bool isExclusive() const;
+ void setExclusive(bool exclusive);
+
public Q_SLOTS:
void setCurrentIndex(int index);
@@ -92,6 +96,7 @@ Q_SIGNALS:
void contentChildrenChanged();
void currentIndexChanged();
void currentItemChanged();
+ void exclusiveChanged();
protected:
QQuickContainer(QQuickContainerPrivate &dd, QQuickItem *parent);
@@ -102,6 +107,7 @@ protected:
private:
Q_DISABLE_COPY(QQuickContainer)
Q_DECLARE_PRIVATE(QQuickContainer)
+ Q_PRIVATE_SLOT(d_func(), void _q_currentItemChanged())
Q_PRIVATE_SLOT(d_func(), void _q_currentIndexChanged())
};
diff --git a/src/templates/qquickcontainer_p_p.h b/src/templates/qquickcontainer_p_p.h
index 49b3a7d3..001e6956 100644
--- a/src/templates/qquickcontainer_p_p.h
+++ b/src/templates/qquickcontainer_p_p.h
@@ -54,6 +54,8 @@
QT_BEGIN_NAMESPACE
+class QQuickExclusiveGroup;
+
class Q_LABSTEMPLATES_EXPORT QQuickContainerPrivate : public QQuickControlPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickContainer)
@@ -72,6 +74,7 @@ public:
void removeItem(int index, QQuickItem *item);
virtual void itemRemoved(QQuickItem *item);
+ void _q_currentItemChanged();
void _q_currentIndexChanged();
void itemChildAdded(QQuickItem *item, QQuickItem *child) Q_DECL_OVERRIDE;
@@ -93,6 +96,7 @@ public:
QQmlObjectModel *contentModel;
int currentIndex;
bool updatingCurrent;
+ QQuickExclusiveGroup *exclusiveGroup;
};
Q_DECLARE_TYPEINFO(QQuickContainerPrivate, Q_COMPLEX_TYPE);
diff --git a/src/templates/qquicktabbar.cpp b/src/templates/qquicktabbar.cpp
index 890e38cb..15564184 100644
--- a/src/templates/qquicktabbar.cpp
+++ b/src/templates/qquicktabbar.cpp
@@ -36,7 +36,6 @@
#include "qquicktabbar_p.h"
#include "qquickcontainer_p_p.h"
-#include "qquickexclusivegroup_p.h"
QT_BEGIN_NAMESPACE
@@ -67,21 +66,12 @@ class QQuickTabBarPrivate : public QQuickContainerPrivate
Q_DECLARE_PUBLIC(QQuickTabBar)
public:
- QQuickTabBarPrivate() : group(Q_NULLPTR)
+ QQuickTabBarPrivate()
{
m_accessibleRole = 0x0000003C; //QAccessible::PageTabList
}
void updateLayout();
- void updateCurrent();
-
- void itemInserted(int index, QQuickItem *item) Q_DECL_OVERRIDE;
- void itemMoved(int from, int to) Q_DECL_OVERRIDE;
- void itemRemoved(QQuickItem *item) Q_DECL_OVERRIDE;
-
- void onCurrentIndexChanged();
-
- QQuickExclusiveGroup *group;
};
void QQuickTabBarPrivate::updateLayout()
@@ -104,45 +94,11 @@ void QQuickTabBarPrivate::updateLayout()
}
}
-void QQuickTabBarPrivate::updateCurrent()
-{
- Q_Q(QQuickTabBar);
- q->setCurrentIndex(contentModel->indexOf(group->current(), Q_NULLPTR));
-}
-
-void QQuickTabBarPrivate::itemInserted(int, QQuickItem *item)
-{
- group->addCheckable(item);
-}
-
-void QQuickTabBarPrivate::itemMoved(int, int)
-{
- updateCurrent();
-}
-
-void QQuickTabBarPrivate::itemRemoved(QQuickItem *item)
-{
- group->removeCheckable(item);
-}
-
-void QQuickTabBarPrivate::onCurrentIndexChanged()
-{
- Q_Q(QQuickTabBar);
- if (q->isComponentComplete())
- group->setCurrent(contentModel->get(currentIndex));
-}
-
QQuickTabBar::QQuickTabBar(QQuickItem *parent) :
QQuickContainer(*(new QQuickTabBarPrivate), parent)
{
- Q_D(QQuickTabBar);
+ setExclusive(true);
setFlag(ItemIsFocusScope);
-
- d->group = new QQuickExclusiveGroup(this);
- connect(d->group, &QQuickExclusiveGroup::currentChanged, this, &QQuickTabBar::currentItemChanged);
- QObjectPrivate::connect(d->group, &QQuickExclusiveGroup::currentChanged, d, &QQuickTabBarPrivate::updateCurrent);
-
- QObjectPrivate::connect(this, &QQuickContainer::currentIndexChanged, d, &QQuickTabBarPrivate::onCurrentIndexChanged);
}
void QQuickTabBar::updatePolish()