aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-04-29 09:55:05 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-06-11 15:12:56 +0000
commit3dab48bcc532f44acc0370d056329a2e5a6b7b6e (patch)
treebbd2dffec81d1bf101565ef4d46beefdd19b68dc
parentf944c34757baf145f7018e37bc732d061f0bbf7f (diff)
Import the new TabBar implementation
Change-Id: I2c646c07f8310c27f3f03f3cdb27f748c5e6198c Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
-rw-r--r--src/controls/qquicktabbar.cpp182
-rw-r--r--src/controls/qquicktabbar_p.h26
-rw-r--r--src/imports/controls/TabBar.qml27
3 files changed, 208 insertions, 27 deletions
diff --git a/src/controls/qquicktabbar.cpp b/src/controls/qquicktabbar.cpp
index 340c2701..74766d1b 100644
--- a/src/controls/qquicktabbar.cpp
+++ b/src/controls/qquicktabbar.cpp
@@ -36,6 +36,10 @@
#include "qquicktabbar_p.h"
#include "qquickcontainer_p_p.h"
+#include "qquickexclusivegroup_p.h"
+
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQml/private/qqmlobjectmodel_p.h>
QT_BEGIN_NAMESPACE
@@ -52,17 +56,84 @@ QT_BEGIN_NAMESPACE
class QQuickTabBarPrivate : public QQuickContainerPrivate
{
+ Q_DECLARE_PUBLIC(QQuickTabBar)
+
public:
- QQuickTabBarPrivate() : currentIndex(0) { }
+ QQuickTabBarPrivate() : currentIndex(0), model(Q_NULLPTR), group(Q_NULLPTR) { }
+
+ void updateLayout();
+ void updateCurrent();
+
+ // TODO: implement the whole list property
+ static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj);
int currentIndex;
+ QQmlObjectModel *model;
+ QQuickExclusiveGroup *group;
};
+void QQuickTabBarPrivate::updateLayout()
+{
+ const int count = model->count();
+ if (count > 0 && contentItem) {
+ const qreal spacing = contentItem->property("spacing").toReal();
+ const qreal itemWidth = (contentItem->width() - qMax(0, count - 1) * spacing) / count;
+
+ for (int i = 0; i < count; ++i) {
+ QQuickItem *item = qobject_cast<QQuickItem *>(model->get(i));
+ if (item) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+ if (!p->widthValid) {
+ item->setWidth(itemWidth);
+ p->widthValid = false;
+ }
+ }
+ }
+ }
+}
+
+void QQuickTabBarPrivate::updateCurrent()
+{
+ Q_Q(QQuickTabBar);
+ q->setCurrentIndex(model->indexOf(group->current(), Q_NULLPTR));
+}
+
+void QQuickTabBarPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
+{
+ QQuickTabBar *bar = static_cast<QQuickTabBar *>(prop->object);
+ QQuickItem *item = qobject_cast<QQuickItem *>(obj);
+ if (item)
+ bar->addItem(item);
+ else
+ QQuickItemPrivate::data_append(prop, obj);
+}
+
QQuickTabBar::QQuickTabBar(QQuickItem *parent) :
QQuickContainer(*(new QQuickTabBarPrivate), parent)
{
+ Q_D(QQuickTabBar);
setFlag(ItemIsFocusScope);
setActiveFocusOnTab(true);
+
+ d->model = new QQmlObjectModel(this);
+ connect(d->model, &QQmlObjectModel::countChanged, this, &QQuickTabBar::countChanged);
+ QObjectPrivate::connect(d->model, &QQmlObjectModel::countChanged, d, &QQuickTabBarPrivate::updateLayout);
+
+ d->group = new QQuickExclusiveGroup(this);
+ connect(d->group, &QQuickExclusiveGroup::currentChanged, this, &QQuickTabBar::currentItemChanged);
+ QObjectPrivate::connect(d->group, &QQuickExclusiveGroup::currentChanged, d, &QQuickTabBarPrivate::updateCurrent);
+}
+
+/*!
+ \qmlproperty int QtQuickControls2::TabBar::count
+ \readonly
+
+ TODO
+*/
+int QQuickTabBar::count() const
+{
+ Q_D(const QQuickTabBar);
+ return d->model->count();
}
/*!
@@ -81,8 +152,115 @@ void QQuickTabBar::setCurrentIndex(int index)
Q_D(QQuickTabBar);
if (d->currentIndex != index) {
d->currentIndex = index;
- emit currentIndexChanged(index);
+ emit currentIndexChanged();
}
}
+/*!
+ \qmlproperty Item QtQuickControls2::TabBar::currentItem
+
+ TODO
+*/
+QQuickItem *QQuickTabBar::currentItem() const
+{
+ Q_D(const QQuickTabBar);
+ return qobject_cast<QQuickItem *>(d->group->current());
+}
+
+/*!
+ \qmlproperty model QtQuickControls2::TabBar::model
+ \readonly
+
+ TODO
+*/
+QVariant QQuickTabBar::model() const
+{
+ Q_D(const QQuickTabBar);
+ return QVariant::fromValue(d->model);
+}
+
+QQmlListProperty<QObject> QQuickTabBar::contentData()
+{
+ Q_D(QQuickTabBar);
+ // TODO: implement the whole list property
+ return QQmlListProperty<QObject>(this, d,
+ QQuickTabBarPrivate::contentData_append,
+ QQuickItemPrivate::data_count,
+ QQuickItemPrivate::data_at,
+ QQuickItemPrivate::data_clear);
+}
+
+/*!
+ \qmlmethod Item QtQuickControls2::TabBar::itemAt(int index)
+
+ TODO
+*/
+QQuickItem *QQuickTabBar::itemAt(int index) const
+{
+ Q_D(const QQuickTabBar);
+ return qobject_cast<QQuickItem *>(d->model->get(index));
+}
+
+/*!
+ \qmlmethod void QtQuickControls2::TabBar::addItem(Item item)
+
+ TODO
+*/
+void QQuickTabBar::addItem(QQuickItem *item)
+{
+ Q_D(QQuickTabBar);
+ insertItem(d->model->count(), item);
+}
+
+/*!
+ \qmlmethod void QtQuickControls2::TabBar::insertItem(int index, Item item)
+
+ TODO
+*/
+void QQuickTabBar::insertItem(int index, QQuickItem *item)
+{
+ Q_D(QQuickTabBar);
+ d->model->insert(index, item);
+ d->group->addCheckable(item);
+ if (d->currentIndex == index)
+ d->group->setCurrent(item);
+}
+
+/*!
+ \qmlmethod void QtQuickControls2::TabBar::moveItem(int from, int to)
+
+ TODO
+*/
+void QQuickTabBar::moveItem(int from, int to)
+{
+ Q_D(QQuickTabBar);
+ d->model->move(from, to);
+}
+
+/*!
+ \qmlmethod void QtQuickControls2::TabBar::removeItem(int index)
+
+ TODO
+*/
+void QQuickTabBar::removeItem(int index)
+{
+ Q_D(QQuickTabBar);
+ d->group->removeCheckable(d->model->get(index));
+ d->model->remove(index);
+}
+
+void QQuickTabBar::componentComplete()
+{
+ Q_D(QQuickTabBar);
+ QQuickContainer::componentComplete();
+ d->updateCurrent();
+}
+
+void QQuickTabBar::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickTabBar);
+ QQuickContainer::geometryChanged(newGeometry, oldGeometry);
+ d->updateLayout();
+}
+
QT_END_NAMESPACE
diff --git a/src/controls/qquicktabbar_p.h b/src/controls/qquicktabbar_p.h
index aee165a9..7d43e24e 100644
--- a/src/controls/qquicktabbar_p.h
+++ b/src/controls/qquicktabbar_p.h
@@ -49,6 +49,7 @@
//
#include <QtQuickControls/private/qquickcontainer_p.h>
+#include <QtQml/qqmllist.h>
QT_BEGIN_NAMESPACE
@@ -57,23 +58,44 @@ class QQuickTabBarPrivate;
class Q_QUICKCONTROLS_EXPORT QQuickTabBar : public QQuickContainer
{
Q_OBJECT
+ Q_PROPERTY(int count READ count NOTIFY countChanged FINAL)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL)
+ Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL)
+ Q_PROPERTY(QVariant model READ model CONSTANT FINAL)
+ Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData)
+ Q_CLASSINFO("DefaultProperty", "contentData")
public:
explicit QQuickTabBar(QQuickItem *parent = Q_NULLPTR);
+ int count() const;
int currentIndex() const;
+ QQuickItem *currentItem() const;
+
+ QVariant model() const;
+ QQmlListProperty<QObject> contentData();
+
+ Q_INVOKABLE QQuickItem *itemAt(int index) const;
+ Q_INVOKABLE void addItem(QQuickItem *item);
+ Q_INVOKABLE void insertItem(int index, QQuickItem *item);
+ Q_INVOKABLE void moveItem(int from, int to);
+ Q_INVOKABLE void removeItem(int index);
public Q_SLOTS:
void setCurrentIndex(int index);
Q_SIGNALS:
- void currentIndexChanged(int index);
+ void countChanged();
+ void currentIndexChanged();
+ void currentItemChanged();
+
+protected:
+ void componentComplete() Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QQuickTabBar)
Q_DECLARE_PRIVATE(QQuickTabBar)
- friend class QQuickTabView;
};
QT_END_NAMESPACE
diff --git a/src/imports/controls/TabBar.qml b/src/imports/controls/TabBar.qml
index 845cf3d0..93d30f35 100644
--- a/src/imports/controls/TabBar.qml
+++ b/src/imports/controls/TabBar.qml
@@ -40,14 +40,7 @@ import QtQuick.Controls 2.0
AbstractTabBar {
id: control
- property list<Item> items
- readonly property int count: items.length
property alias highlight: listView.highlight
- property alias spacing: listView.spacing
-
- property Component delegate: TabButton {
- width: (listView.width - Math.max(0, count - 1) * spacing) / count
- }
contentWidth: listView.contentWidth
contentHeight: listView.contentHeight
@@ -57,10 +50,6 @@ AbstractTabBar {
Accessible.role: Accessible.PageTabList
- ExclusiveGroup {
- id: group
- }
-
contentItem: ListView {
id: listView
@@ -69,18 +58,9 @@ AbstractTabBar {
boundsBehavior: Flickable.StopAtBounds
snapMode: ListView.SnapToItem
- model: control.items
+ model: control.model
currentIndex: control.currentIndex
- delegate: Loader {
- sourceComponent: control.delegate
- visible: modelData.Tab.visible
- Binding { target: item; property: "Exclusive.group"; value: group }
- Binding { target: item; property: "text"; value: modelData.Tab.title }
- Binding { target: item; property: "checked"; value: control.currentIndex === index }
- Connections { target: item; onClicked: control.currentIndex = index }
- }
-
highlightMoveDuration: 250
highlightResizeDuration: 0
highlightFollowsCurrentItem: true
@@ -98,10 +78,11 @@ AbstractTabBar {
background: Rectangle {
implicitWidth: 26
implicitHeight: 26
- width: listView.width
+
border.color: control.Theme.backgroundColor
border.width: 8
- color: listView.count > 1 ? control.Theme.frameColor : control.Theme.backgroundColor
+ color: control.count > 1 ? control.Theme.frameColor : control.Theme.backgroundColor
+
Rectangle {
y: parent.height - height
width: parent.width