From 1fd8a2fc11926dc405d71aafbbfc274c82a574de Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 17 Apr 2018 12:53:02 +0200 Subject: Merge QQuickPageLayout to QQuickPage The idea of a separate QQuickPageLayout falls a bit short, because as a non-QObject it cannot e.g. emit signals when the headers and footers change as a result of being destroyed. Next, we want to add implicit header and footer sizes, which has the same problem. QQuickPageLayout is currently used by QQuickPage and QQuickDialog. We are now moving the functionality to QQuickPage, and will use QQuickPage in QQuickDialog instead. Change-Id: I869e6ba0056d424e617c48c2e4f591c75cde48e5 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickpage.cpp | 166 +++++++++++++++++++++++++++++++------ src/quicktemplates2/qquickpage_p.h | 3 +- 2 files changed, 142 insertions(+), 27 deletions(-) diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index b8838f20..0a7a3476 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -36,7 +36,9 @@ #include "qquickpage_p.h" #include "qquickpane_p_p.h" -#include "qquickpagelayout_p_p.h" +#include "qquicktabbar_p.h" +#include "qquicktoolbar_p.h" +#include "qquickdialogbuttonbox_p.h" QT_BEGIN_NAMESPACE @@ -84,20 +86,122 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls 2} */ +static const QQuickItemPrivate::ChangeTypes LayoutChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed + | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + +namespace { + enum Position { + Header, + Footer + }; + + Q_STATIC_ASSERT(int(Header) == int(QQuickTabBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickTabBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickToolBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickToolBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickDialogButtonBox::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickDialogButtonBox::Footer)); + + static void setPos(QQuickItem *item, Position position) + { + if (QQuickToolBar *toolBar = qobject_cast(item)) + toolBar->setPosition(static_cast(position)); + else if (QQuickTabBar *tabBar = qobject_cast(item)) + tabBar->setPosition(static_cast(position)); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast(item)) + buttonBox->setPosition(static_cast(position)); + } +} + class QQuickPagePrivate : public QQuickPanePrivate { Q_DECLARE_PUBLIC(QQuickPage) public: + void relayout(); + void resizeContent() override; + + void itemVisibilityChanged(QQuickItem *item) override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) override; + void itemDestroyed(QQuickItem *item) override; + QString title; - QScopedPointer layout; + QQuickItem *header = nullptr; + QQuickItem *footer = nullptr; }; +void QQuickPagePrivate::relayout() +{ + Q_Q(QQuickPage); + const qreal hh = header && header->isVisible() ? header->height() : 0; + const qreal fh = footer && footer->isVisible() ? footer->height() : 0; + const qreal hsp = hh > 0 ? spacing : 0; + const qreal fsp = fh > 0 ? spacing : 0; + + if (contentItem) { + contentItem->setY(q->topPadding() + hh + hsp); + contentItem->setX(q->leftPadding()); + contentItem->setWidth(q->availableWidth()); + contentItem->setHeight(q->availableHeight() - hh - fh - hsp - fsp); + } + + if (header) + header->setWidth(q->width()); + + if (footer) { + footer->setY(q->height() - footer->height()); + footer->setWidth(q->width()); + } +} + +void QQuickPagePrivate::resizeContent() +{ + relayout(); +} + +void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item) +{ + QQuickPanePrivate::itemVisibilityChanged(item); + if (item == header || item == footer) + relayout(); +} + +void QQuickPagePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) +{ + QQuickPanePrivate::itemGeometryChanged(item, change, diff); + if (item == header || item == footer) + relayout(); +} + +void QQuickPagePrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemDestroyed(item); + if (item == header) { + header = nullptr; + relayout(); + emit q->headerChanged(); + } else if (item == footer) { + footer = nullptr; + relayout(); + emit q->footerChanged(); + } +} + QQuickPage::QQuickPage(QQuickItem *parent) : QQuickPane(*(new QQuickPagePrivate), parent) +{ +} + +QQuickPage::~QQuickPage() { Q_D(QQuickPage); - d->layout.reset(new QQuickPageLayout(this)); + if (d->header) + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + if (d->footer) + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); } /*! @@ -168,16 +272,29 @@ void QQuickPage::setTitle(const QString &title) QQuickItem *QQuickPage::header() const { Q_D(const QQuickPage); - return d->layout->header(); + return d->header; } void QQuickPage::setHeader(QQuickItem *header) { Q_D(QQuickPage); - if (!d->layout->setHeader(header)) + if (d->header == header) return; + + if (d->header) { + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + d->header->setParentItem(nullptr); + } + d->header = header; + if (header) { + header->setParentItem(this); + QQuickItemPrivate::get(header)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(header->z())) + header->setZ(1); + setPos(header, Header); + } if (isComponentComplete()) - d->layout->update(); + d->relayout(); emit headerChanged(); } @@ -196,16 +313,29 @@ void QQuickPage::setHeader(QQuickItem *header) QQuickItem *QQuickPage::footer() const { Q_D(const QQuickPage); - return d->layout->footer(); + return d->footer; } void QQuickPage::setFooter(QQuickItem *footer) { Q_D(QQuickPage); - if (!d->layout->setFooter(footer)) + if (d->footer == footer) return; + + if (d->footer) { + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); + footer->setParentItem(nullptr); + } + d->footer = footer; + if (footer) { + footer->setParentItem(this); + QQuickItemPrivate::get(footer)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(footer->z())) + footer->setZ(1); + setPos(footer, Footer); + } if (isComponentComplete()) - d->layout->update(); + d->relayout(); emit footerChanged(); } @@ -213,28 +343,14 @@ void QQuickPage::componentComplete() { Q_D(QQuickPage); QQuickPane::componentComplete(); - d->layout->update(); -} - -void QQuickPage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_D(QQuickPage); - QQuickPane::geometryChanged(newGeometry, oldGeometry); - d->layout->update(); -} - -void QQuickPage::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) -{ - Q_D(QQuickPage); - QQuickPane::paddingChange(newPadding, oldPadding); - d->layout->update(); + d->relayout(); } void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing) { Q_D(QQuickPage); QQuickPane::spacingChange(newSpacing, oldSpacing); - d->layout->update(); + d->relayout(); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h index 49f9f85f..f6bbaa0c 100644 --- a/src/quicktemplates2/qquickpage_p.h +++ b/src/quicktemplates2/qquickpage_p.h @@ -67,6 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickPane public: explicit QQuickPage(QQuickItem *parent = nullptr); + ~QQuickPage(); QString title() const; void setTitle(const QString &title); @@ -85,8 +86,6 @@ Q_SIGNALS: protected: void componentComplete() override; - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; - void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override; void spacingChange(qreal newSpacing, qreal oldSpacing) override; #if QT_CONFIG(accessibility) -- cgit v1.2.3