diff options
Diffstat (limited to 'src/quicktemplates2/qquickpage.cpp')
-rw-r--r-- | src/quicktemplates2/qquickpage.cpp | 332 |
1 files changed, 211 insertions, 121 deletions
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 25dce5e6..93196c4c 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -35,14 +35,16 @@ ****************************************************************************/ #include "qquickpage_p.h" -#include "qquickcontrol_p_p.h" -#include "qquickpagelayout_p_p.h" +#include "qquickpage_p_p.h" +#include "qquicktabbar_p.h" +#include "qquicktoolbar_p.h" +#include "qquickdialogbuttonbox_p.h" QT_BEGIN_NAMESPACE /*! \qmltype Page - \inherits Control + \inherits Pane \instantiates QQuickPage \inqmlmodule QtQuick.Controls \since 5.7 @@ -84,37 +86,142 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls 2} */ -class QQuickPagePrivate : public QQuickControlPrivate +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<QQuickToolBar *>(item)) + toolBar->setPosition(static_cast<QQuickToolBar::Position>(position)); + else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(item)) + tabBar->setPosition(static_cast<QQuickTabBar::Position>(position)); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(item)) + buttonBox->setPosition(static_cast<QQuickDialogButtonBox::Position>(position)); + } +} + +void QQuickPagePrivate::relayout() { - Q_DECLARE_PUBLIC(QQuickPage) + 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); + } -public: - QQuickItem *getContentItem() override; + if (header) + header->setWidth(q->width()); - qreal contentWidth = 0; - qreal contentHeight = 0; - QString title; - QScopedPointer<QQuickPageLayout> layout; -}; + if (footer) { + footer->setY(q->height() - footer->height()); + footer->setWidth(q->width()); + } +} + +void QQuickPagePrivate::resizeContent() +{ + relayout(); +} -QQuickItem *QQuickPagePrivate::getContentItem() +void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item) { Q_Q(QQuickPage); - if (QQuickItem *item = QQuickControlPrivate::getContentItem()) - return item; - return new QQuickItem(q); + QQuickPanePrivate::itemVisibilityChanged(item); + if (item == header) { + emit q->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + relayout(); + } else if (item == footer) { + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + relayout(); + } +} + +void QQuickPagePrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemImplicitWidthChanged(item); + if (item == header) + emit q->implicitHeaderWidthChanged(); + else if (item == footer) + emit q->implicitFooterWidthChanged(); +} + +void QQuickPagePrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemImplicitHeightChanged(item); + if (item == header) + emit q->implicitHeaderHeightChanged(); + else if (item == footer) + emit q->implicitFooterHeightChanged(); +} + +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->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + emit q->headerChanged(); + } else if (item == footer) { + footer = nullptr; + relayout(); + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + emit q->footerChanged(); + } } QQuickPage::QQuickPage(QQuickItem *parent) - : QQuickControl(*(new QQuickPagePrivate), parent) + : QQuickPane(*(new QQuickPagePrivate), parent) +{ +} + +QQuickPage::QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent) + : QQuickPane(dd, parent) +{ +} + +QQuickPage::~QQuickPage() { Q_D(QQuickPage); - setFlag(ItemIsFocusScope); - setAcceptedMouseButtons(Qt::AllButtons); -#if QT_CONFIG(cursor) - setCursor(Qt::ArrowCursor); -#endif - 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); } /*! @@ -185,16 +292,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(); } @@ -213,150 +333,120 @@ 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(); } /*! - \qmlproperty list<Object> QtQuick.Controls::Page::contentData - \default + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderWidth + \readonly - This property holds the list of content data. + This property holds the implicit header width. - The list contains all objects that have been declared in QML as children - of the container. + The value is equal to \c {header && header.visible ? header.implicitWidth : 0}. - \note Unlike \c contentChildren, \c contentData does include non-visual QML - objects. - - \sa Item::data, contentChildren + \sa implicitHeaderHeight, implicitFooterWidth */ -QQmlListProperty<QObject> QQuickPage::contentData() +qreal QQuickPage::implicitHeaderWidth() const { - return QQmlListProperty<QObject>(contentItem(), nullptr, - QQuickItemPrivate::data_append, - QQuickItemPrivate::data_count, - QQuickItemPrivate::data_at, - QQuickItemPrivate::data_clear); + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitWidth(); } /*! - \qmlproperty list<Item> QtQuick.Controls::Page::contentChildren + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderHeight + \readonly - This property holds the list of content children. + This property holds the implicit header height. - The list contains all items that have been declared in QML as children - of the page. + The value is equal to \c {header && header.visible ? header.implicitHeight : 0}. - \note Unlike \c contentData, \c contentChildren does not include non-visual - QML objects. - - \sa Item::children, contentData + \sa implicitHeaderWidth, implicitFooterHeight */ -QQmlListProperty<QQuickItem> QQuickPage::contentChildren() +qreal QQuickPage::implicitHeaderHeight() const { - return QQmlListProperty<QQuickItem>(contentItem(), nullptr, - QQuickItemPrivate::children_append, - QQuickItemPrivate::children_count, - QQuickItemPrivate::children_at, - QQuickItemPrivate::children_clear); + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitHeight(); } /*! - \qmlproperty real QtQuick.Controls::Page::contentWidth - \since QtQuick.Controls 2.1 (Qt 5.8) + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterWidth + \readonly + + This property holds the implicit footer width. - This property holds the content width. It is used for calculating the total - implicit width of the page. + The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}. - \sa contentHeight + \sa implicitFooterHeight, implicitHeaderWidth */ -qreal QQuickPage::contentWidth() const +qreal QQuickPage::implicitFooterWidth() const { Q_D(const QQuickPage); - return d->contentWidth; -} - -void QQuickPage::setContentWidth(qreal width) -{ - Q_D(QQuickPage); - if (qFuzzyCompare(d->contentWidth, width)) - return; - - d->contentWidth = width; - emit contentWidthChanged(); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitWidth(); } /*! - \qmlproperty real QtQuick.Controls::Page::contentHeight - \since QtQuick.Controls 2.1 (Qt 5.8) + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterHeight + \readonly - This property holds the content height. It is used for calculating the total - implicit height of the page. + This property holds the implicit footer height. - \sa contentWidth + The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}. + + \sa implicitFooterWidth, implicitHeaderHeight */ -qreal QQuickPage::contentHeight() const +qreal QQuickPage::implicitFooterHeight() const { Q_D(const QQuickPage); - return d->contentHeight; -} - -void QQuickPage::setContentHeight(qreal height) -{ - Q_D(QQuickPage); - if (qFuzzyCompare(d->contentHeight, height)) - return; - - d->contentHeight = height; - emit contentHeightChanged(); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitHeight(); } void QQuickPage::componentComplete() { Q_D(QQuickPage); - QQuickControl::componentComplete(); - d->layout->update(); -} - -void QQuickPage::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) -{ - QQuickControl::contentItemChange(newItem, oldItem); - if (oldItem) - disconnect(oldItem, &QQuickItem::childrenChanged, this, &QQuickPage::contentChildrenChanged); - if (newItem) - connect(newItem, &QQuickItem::childrenChanged, this, &QQuickPage::contentChildrenChanged); - emit contentChildrenChanged(); -} - -void QQuickPage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_D(QQuickPage); - QQuickControl::geometryChanged(newGeometry, oldGeometry); - d->layout->update(); -} - -void QQuickPage::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) -{ - Q_D(QQuickPage); - QQuickControl::paddingChange(newPadding, oldPadding); - d->layout->update(); + QQuickPane::componentComplete(); + d->relayout(); } void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing) { Q_D(QQuickPage); - QQuickControl::spacingChange(newSpacing, oldSpacing); - d->layout->update(); + QQuickPane::spacingChange(newSpacing, oldSpacing); + d->relayout(); } #if QT_CONFIG(accessibility) @@ -368,7 +458,7 @@ QAccessible::Role QQuickPage::accessibleRole() const void QQuickPage::accessibilityActiveChanged(bool active) { Q_D(QQuickPage); - QQuickControl::accessibilityActiveChanged(active); + QQuickPane::accessibilityActiveChanged(active); if (active) setAccessibleName(d->title); |