diff options
Diffstat (limited to 'src/quicktemplates2/qquicktabbar.cpp')
-rw-r--r-- | src/quicktemplates2/qquicktabbar.cpp | 186 |
1 files changed, 159 insertions, 27 deletions
diff --git a/src/quicktemplates2/qquicktabbar.cpp b/src/quicktemplates2/qquicktabbar.cpp index b32e55d3..7ce8a21e 100644 --- a/src/quicktemplates2/qquicktabbar.cpp +++ b/src/quicktemplates2/qquicktabbar.cpp @@ -105,14 +105,26 @@ public: void updateLayout(); void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; bool updatingLayout; + bool hasContentWidth; + bool hasContentHeight; + qreal contentWidth; + qreal contentHeight; QQuickTabBar::Position position; }; -QQuickTabBarPrivate::QQuickTabBarPrivate() : updatingLayout(false), position(QQuickTabBar::Header) +QQuickTabBarPrivate::QQuickTabBarPrivate() + : updatingLayout(false), + hasContentWidth(false), + hasContentHeight(false), + contentWidth(0), + contentHeight(0), + position(QQuickTabBar::Header) { - changeTypes |= Geometry; + changeTypes |= Geometry | ImplicitWidth | ImplicitHeight; } void QQuickTabBarPrivate::updateCurrentItem() @@ -134,34 +146,61 @@ void QQuickTabBarPrivate::updateLayout() { Q_Q(QQuickTabBar); const int count = contentModel->count(); - if (count > 0 && contentItem) { - qreal reservedWidth = 0; - QVector<QQuickItem *> resizableItems; - resizableItems.reserve(count); - - for (int i = 0; i < count; ++i) { - QQuickItem *item = q->itemAt(i); - if (item) { - QQuickItemPrivate *p = QQuickItemPrivate::get(item); - if (!p->widthValid) - resizableItems += item; - else - reservedWidth += item->width(); + if (count <= 0 || !contentItem) + return; + + qreal maxHeight = 0; + qreal totalWidth = 0; + qreal reservedWidth = 0; + + QVector<QQuickItem *> resizableItems; + resizableItems.reserve(count); + + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid) { + resizableItems += item; + totalWidth += item->implicitWidth(); + } else { + reservedWidth += item->width(); + totalWidth += item->width(); } + maxHeight = qMax(maxHeight, item->implicitHeight()); } + } - if (!resizableItems.isEmpty()) { - const qreal totalSpacing = qMax(0, count - 1) * spacing; - const qreal itemWidth = (contentItem->width() - reservedWidth - totalSpacing) / resizableItems.count(); + const qreal totalSpacing = qMax(0, count - 1) * spacing; + totalWidth += totalSpacing; - updatingLayout = true; - for (QQuickItem *item : qAsConst(resizableItems)) { - item->setWidth(itemWidth); - QQuickItemPrivate::get(item)->widthValid = false; - } - updatingLayout = false; + if (!resizableItems.isEmpty()) { + const qreal itemWidth = (contentItem->width() - reservedWidth - totalSpacing) / resizableItems.count(); + + updatingLayout = true; + for (QQuickItem *item : qAsConst(resizableItems)) { + item->setWidth(itemWidth); + QQuickItemPrivate::get(item)->widthValid = false; } + updatingLayout = false; + } + + bool contentWidthChange = false; + if (!hasContentWidth && !qFuzzyCompare(contentWidth, totalWidth)) { + contentWidth = totalWidth; + contentWidthChange = true; + } + + bool contentHeightChange = false; + if (!hasContentHeight && !qFuzzyCompare(contentHeight, maxHeight)) { + contentHeight = maxHeight; + contentHeightChange = true; } + + if (contentWidthChange) + emit q->contentWidthChanged(); + if (contentHeightChange) + emit q->contentHeightChanged(); } void QQuickTabBarPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) @@ -170,8 +209,20 @@ void QQuickTabBarPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange updateLayout(); } -QQuickTabBar::QQuickTabBar(QQuickItem *parent) : - QQuickContainer(*(new QQuickTabBarPrivate), parent) +void QQuickTabBarPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + if (!updatingLayout && !hasContentWidth) + updateLayout(); +} + +void QQuickTabBarPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + if (!updatingLayout && !hasContentHeight) + updateLayout(); +} + +QQuickTabBar::QQuickTabBar(QQuickItem *parent) + : QQuickContainer(*(new QQuickTabBarPrivate), parent) { Q_D(QQuickTabBar); setFlag(ItemIsFocusScope); @@ -210,6 +261,87 @@ void QQuickTabBar::setPosition(Position position) emit positionChanged(); } +/*! + \since QtQuick.Controls 2.2 + \qmlproperty real QtQuick.Controls::TabBar::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the tab bar. + + Unless explicitly overridden, the content width is automatically calculated + based on the total implicit width of the tabs and the \l {Control::}{spacing} + of the tab bar. + + \sa contentHeight +*/ +qreal QQuickTabBar::contentWidth() const +{ + Q_D(const QQuickTabBar); + return d->contentWidth; +} + +void QQuickTabBar::setContentWidth(qreal width) +{ + Q_D(QQuickTabBar); + d->hasContentWidth = true; + if (qFuzzyCompare(d->contentWidth, width)) + return; + + d->contentWidth = width; + emit contentWidthChanged(); +} + +void QQuickTabBar::resetContentWidth() +{ + Q_D(QQuickTabBar); + if (!d->hasContentWidth) + return; + + d->hasContentWidth = false; + if (isComponentComplete()) + d->updateLayout(); +} + +/*! + \since QtQuick.Controls 2.2 + \qmlproperty real QtQuick.Controls::TabBar::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the tab bar. + + Unless explicitly overridden, the content height is automatically calculated + based on the maximum implicit height of the tabs. + + \sa contentWidth +*/ +qreal QQuickTabBar::contentHeight() const +{ + Q_D(const QQuickTabBar); + return d->contentHeight; +} + +void QQuickTabBar::setContentHeight(qreal height) +{ + Q_D(QQuickTabBar); + d->hasContentHeight = true; + if (qFuzzyCompare(d->contentHeight, height)) + return; + + d->contentHeight = height; + emit contentHeightChanged(); +} + +void QQuickTabBar::resetContentHeight() +{ + Q_D(QQuickTabBar); + if (!d->hasContentHeight) + return; + + d->hasContentHeight = false; + if (isComponentComplete()) + d->updateLayout(); +} + void QQuickTabBar::updatePolish() { Q_D(QQuickTabBar); @@ -258,7 +390,7 @@ void QQuickTabBar::itemRemoved(int index, QQuickItem *item) polish(); } -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) QAccessible::Role QQuickTabBar::accessibleRole() const { return QAccessible::PageTabList; |