diff options
author | Mitch Curtis <[email protected]> | 2021-08-12 14:39:51 +0200 |
---|---|---|
committer | Mitch Curtis <[email protected]> | 2021-08-16 12:52:59 +0200 |
commit | 809339d1484cf556512534367b8170bc26baf072 (patch) | |
tree | 12871313b658f36d058b5ef25af1e247e9c46ce9 /src/quicktemplates2/qquickscrollview.cpp | |
parent | b01b4f00eae8022c6a97d90f54dac395144ae095 (diff) |
Now that qtquickcontrols2 has been merged into qtdeclarative,
we should make it obvious that this repo should no longer be
used, by preventing it from being built.
Task-number: QTBUG-95173
Pick-to: 6.2
Change-Id: I95bd6a214f3d75a865ab163ee0a1f9ffbeb7a051
Reviewed-by: Alexandru Croitor <[email protected]>
Reviewed-by: Volker Hilsheimer <[email protected]>
Diffstat (limited to 'src/quicktemplates2/qquickscrollview.cpp')
-rw-r--r-- | src/quicktemplates2/qquickscrollview.cpp | 623 |
1 files changed, 0 insertions, 623 deletions
diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp deleted file mode 100644 index 1f5adbb7..00000000 --- a/src/quicktemplates2/qquickscrollview.cpp +++ /dev/null @@ -1,623 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickscrollview_p.h" -#include "qquickpane_p_p.h" -#include "qquickscrollbar_p_p.h" - -#include <QtQuick/private/qquickflickable_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \qmltype ScrollView - \inherits Pane -//! \instantiates QQuickScrollView - \inqmlmodule QtQuick.Controls - \since 5.9 - \ingroup qtquickcontrols2-containers - \ingroup qtquickcontrols2-focusscopes - \brief Scrollable view. - - ScrollView provides scrolling for user-defined content. It can be used to - either replace a \l Flickable, or to decorate an existing one. - - \image qtquickcontrols2-scrollview.png - - The first example demonstrates the simplest usage of ScrollView. - - \snippet qtquickcontrols2-scrollview.qml file - - The second example illustrates using an existing \l Flickable, that is, - a \l ListView. - - \snippet qtquickcontrols2-scrollview-listview.qml file - - \note As of Qt-6.0, ScrollView automatically clips its contents if you - don't use a Flickable as a child. If this is not wanted, you can - set your own Flickable as a child, and control the \l {Item::}{clip} - property on the Flickable explicitly. - - \section2 Sizing - - As with Flickable, there are several things to keep in mind when using - ScrollView: - \list - \li If only a single item is used within a ScrollView, the content size is - automatically calculated based on the implicit size of its contained item. - However, if more than one item is used (or an implicit size is not - provided), the \l {QtQuick.Controls::Pane::}{contentWidth} and - \l {QtQuick.Controls::Pane::}{contentHeight} properties must - be set to the combined size of its contained items. - \li If the content size is less than or equal to the size of the ScrollView, - it will not be scrollable. - \li If you want the ScrollView to only scroll vertically, you can bind - \l {QtQuick.Controls::Pane::}{contentWidth} to - \l {QtQuick.Controls::Control::}{availableWidth} - (and vice versa for contentHeight). This will let the contents fill - out all the available space horizontally inside the ScrollView, taking - any padding or scroll bars into account. - \endlist - - \section2 Scroll Bars - - The horizontal and vertical scroll bars can be accessed and customized using - the \l {ScrollBar::horizontal}{ScrollBar.horizontal} and \l {ScrollBar::vertical} - {ScrollBar.vertical} attached properties. The following example adjusts the scroll - bar policies so that the horizontal scroll bar is always off, and the vertical - scroll bar is always on. - - \snippet qtquickcontrols2-scrollview-policy.qml file - - \section2 Touch vs. Mouse Interaction - - On touch, ScrollView enables flicking and makes the scroll bars non-interactive. - - \image qtquickcontrols2-scrollindicator.gif - - When interacted with a mouse device, flicking is disabled and the scroll bars - are interactive. - - \image qtquickcontrols2-scrollbar.gif - - Scroll bars can be made interactive on touch, or non-interactive when interacted - with a mouse device, by setting the \l {ScrollBar::}{interactive} property explicitly - to \c true or \c false, respectively. - - \snippet qtquickcontrols2-scrollview-interactive.qml file - - \sa ScrollBar, ScrollIndicator, {Customizing ScrollView}, {Container Controls}, - {Focus Management in Qt Quick Controls} -*/ - -class QQuickScrollViewPrivate : public QQuickPanePrivate -{ - Q_DECLARE_PUBLIC(QQuickScrollView) - -public: - QQmlListProperty<QObject> contentData() override; - QQmlListProperty<QQuickItem> contentChildren() override; - QList<QQuickItem *> contentChildItems() const override; - - QQuickItem *getContentItem() override; - - QQuickFlickable *ensureFlickable(bool content); - bool setFlickable(QQuickFlickable *flickable, bool content); - - void flickableContentWidthChanged(); - void flickableContentHeightChanged(); - - qreal getContentWidth() const override; - qreal getContentHeight() const override; - - QQuickScrollBar *verticalScrollBar() const; - QQuickScrollBar *horizontalScrollBar() const; - - void setScrollBarsInteractive(bool interactive); - - static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); - static qsizetype contentData_count(QQmlListProperty<QObject> *prop); - static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); - static void contentData_clear(QQmlListProperty<QObject> *prop); - - static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *obj); - static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop); - static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index); - static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); - - void itemImplicitWidthChanged(QQuickItem *item) override; - - bool wasTouched = false; - QQuickFlickable *flickable = nullptr; - bool flickableHasExplicitContentWidth = true; - bool flickableHasExplicitContentHeight = true; -}; - -QList<QQuickItem *> QQuickScrollViewPrivate::contentChildItems() const -{ - if (!flickable) - return QList<QQuickItem *>(); - - return flickable->contentItem()->childItems(); -} - -QQuickItem *QQuickScrollViewPrivate::getContentItem() -{ - if (!contentItem) - executeContentItem(); - return ensureFlickable(false); -} - -QQuickFlickable *QQuickScrollViewPrivate::ensureFlickable(bool content) -{ - Q_Q(QQuickScrollView); - if (!flickable) { - flickableHasExplicitContentWidth = false; - flickableHasExplicitContentHeight = false; - auto flickable = new QQuickFlickable(q); - // We almost always want to clip the flickable so that flickable - // contents doesn't show up outside the scrollview. The only time - // this is not really needed, is when the scrollview covers the whole - // window and the scrollbars are transient. But for that corner case, if this - // optimization is needed, the user can simply create his own flickable - // child inside the scrollview, and control clipping on it explicit. - flickable->setClip(true); - flickable->setPixelAligned(true); - setFlickable(flickable, content); - } - return flickable; -} - -bool QQuickScrollViewPrivate::setFlickable(QQuickFlickable *item, bool content) -{ - Q_Q(QQuickScrollView); - if (item == flickable) - return false; - - QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); - - if (flickable) { - flickable->removeEventFilter(q); - - if (attached) - QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(nullptr); - - QObjectPrivate::disconnect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); - QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged); - QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged); - } - - flickable = item; - if (content) - q->setContentItem(flickable); - - if (flickable) { - flickable->installEventFilter(q); - if (hasContentWidth) - flickable->setContentWidth(contentWidth); - else - flickableContentWidthChanged(); - if (hasContentHeight) - flickable->setContentHeight(contentHeight); - else - flickableContentHeightChanged(); - - if (attached) - QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(flickable); - - QObjectPrivate::connect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); - QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged); - QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged); - } - - return true; -} - -void QQuickScrollViewPrivate::flickableContentWidthChanged() -{ - Q_Q(QQuickScrollView); - if (!flickable || !componentComplete) - return; - - const qreal cw = flickable->contentWidth(); - if (qFuzzyCompare(cw, implicitContentWidth)) - return; - - flickableHasExplicitContentWidth = true; - implicitContentWidth = cw; - emit q->implicitContentWidthChanged(); -} - -void QQuickScrollViewPrivate::flickableContentHeightChanged() -{ - Q_Q(QQuickScrollView); - if (!flickable || !componentComplete) - return; - - const qreal ch = flickable->contentHeight(); - if (qFuzzyCompare(ch, implicitContentHeight)) - return; - - flickableHasExplicitContentHeight = true; - implicitContentHeight = ch; - emit q->implicitContentHeightChanged(); -} - -qreal QQuickScrollViewPrivate::getContentWidth() const -{ - if (flickable && flickableHasExplicitContentWidth) - return flickable->contentWidth(); - - // The scrollview wraps a flickable created by us, and nobody searched for it and - // modified its contentWidth. In that case, since the application does not control - // this flickable, we fall back to calculate the content width based on the child - // items inside it. - return QQuickPanePrivate::getContentWidth(); -} - -qreal QQuickScrollViewPrivate::getContentHeight() const -{ - if (flickable && flickableHasExplicitContentHeight) - return flickable->contentHeight(); - - // The scrollview wraps a flickable created by us, and nobody searched for it and - // modified its contentHeight. In that case, since the application does not control - // this flickable, we fall back to calculate the content height based on the child - // items inside it. - return QQuickPanePrivate::getContentHeight(); -} - -QQuickScrollBar *QQuickScrollViewPrivate::verticalScrollBar() const -{ - Q_Q(const QQuickScrollView); - QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); - if (!attached) - return nullptr; - return attached->vertical(); -} - -QQuickScrollBar *QQuickScrollViewPrivate::horizontalScrollBar() const -{ - Q_Q(const QQuickScrollView); - QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); - if (!attached) - return nullptr; - return attached->horizontal(); -} - -void QQuickScrollViewPrivate::setScrollBarsInteractive(bool interactive) -{ - QQuickScrollBar *hbar = horizontalScrollBar(); - if (hbar) { - QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(hbar); - if (!p->explicitInteractive) - p->setInteractive(interactive); - } - - QQuickScrollBar *vbar = verticalScrollBar(); - if (vbar) { - QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(vbar); - if (!p->explicitInteractive) - p->setInteractive(interactive); - } -} - -void QQuickScrollViewPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable && p->setFlickable(qobject_cast<QQuickFlickable *>(obj), true)) - return; - - QQuickFlickable *flickable = p->ensureFlickable(true); - Q_ASSERT(flickable); - QQmlListProperty<QObject> data = flickable->flickableData(); - data.append(&data, obj); -} - -qsizetype QQuickScrollViewPrivate::contentData_count(QQmlListProperty<QObject> *prop) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return 0; - - QQmlListProperty<QObject> data = p->flickable->flickableData(); - return data.count(&data); -} - -QObject *QQuickScrollViewPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return nullptr; - - QQmlListProperty<QObject> data = p->flickable->flickableData(); - return data.at(&data, index); -} - -void QQuickScrollViewPrivate::contentData_clear(QQmlListProperty<QObject> *prop) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return; - - QQmlListProperty<QObject> data = p->flickable->flickableData(); - return data.clear(&data); -} - -void QQuickScrollViewPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - p->setFlickable(qobject_cast<QQuickFlickable *>(item), true); - - QQuickFlickable *flickable = p->ensureFlickable(true); - Q_ASSERT(flickable); - QQmlListProperty<QQuickItem> children = flickable->flickableChildren(); - children.append(&children, item); -} - -qsizetype QQuickScrollViewPrivate::contentChildren_count(QQmlListProperty<QQuickItem> *prop) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return 0; - - QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); - return children.count(&children); -} - -QQuickItem *QQuickScrollViewPrivate::contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return nullptr; - - QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); - return children.at(&children, index); -} - -void QQuickScrollViewPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop) -{ - QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); - if (!p->flickable) - return; - - QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); - children.clear(&children); -} - -void QQuickScrollViewPrivate::itemImplicitWidthChanged(QQuickItem *item) -{ - // a special case for width<->height dependent content (wrapping text) in ScrollView - if (contentWidth < 0 && !componentComplete) - return; - - QQuickPanePrivate::itemImplicitWidthChanged(item); -} - -QQuickScrollView::QQuickScrollView(QQuickItem *parent) - : QQuickPane(*(new QQuickScrollViewPrivate), parent) -{ - Q_D(QQuickScrollView); - d->contentWidth = -1; - d->contentHeight = -1; - - setFiltersChildMouseEvents(true); - setWheelEnabled(true); -} - -/*! - \qmlproperty list<Object> QtQuick.Controls::ScrollView::contentData - \qmldefault - - This property holds the list of content data. - - The list contains all objects that have been declared in QML as children of the view. - - \note Unlike \c contentChildren, \c contentData does include non-visual QML objects. - - \sa Item::data, contentChildren -*/ -QQmlListProperty<QObject> QQuickScrollViewPrivate::contentData() -{ - Q_Q(QQuickScrollView); - return QQmlListProperty<QObject>(q, this, - QQuickScrollViewPrivate::contentData_append, - QQuickScrollViewPrivate::contentData_count, - QQuickScrollViewPrivate::contentData_at, - QQuickScrollViewPrivate::contentData_clear); -} - -/*! - \qmlproperty list<Item> QtQuick.Controls::ScrollView::contentChildren - - This property holds the list of content children. - - The list contains all items that have been declared in QML as children of the view. - - \note Unlike \c contentData, \c contentChildren does not include non-visual QML objects. - - \sa Item::children, contentData -*/ -QQmlListProperty<QQuickItem> QQuickScrollViewPrivate::contentChildren() -{ - Q_Q(QQuickScrollView); - return QQmlListProperty<QQuickItem>(q, this, - QQuickScrollViewPrivate::contentChildren_append, - QQuickScrollViewPrivate::contentChildren_count, - QQuickScrollViewPrivate::contentChildren_at, - QQuickScrollViewPrivate::contentChildren_clear); -} - -bool QQuickScrollView::childMouseEventFilter(QQuickItem *item, QEvent *event) -{ - Q_D(QQuickScrollView); - switch (event->type()) { - case QEvent::TouchBegin: - d->wasTouched = true; - d->setScrollBarsInteractive(false); - return false; - - case QEvent::TouchEnd: - d->wasTouched = false; - return false; - - case QEvent::MouseButtonPress: - // NOTE: Flickable does not handle touch events, only synthesized mouse events - if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) { - d->wasTouched = false; - d->setScrollBarsInteractive(true); - return false; - } - return !d->wasTouched && item == d->flickable; - - case QEvent::MouseMove: - case QEvent::MouseButtonRelease: - if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) - return item == d->flickable; - break; - - case QEvent::HoverEnter: - case QEvent::HoverMove: - if (d->wasTouched && (item == d->verticalScrollBar() || item == d->horizontalScrollBar())) - d->setScrollBarsInteractive(true); - break; - - default: - break; - } - - return false; -} - -bool QQuickScrollView::eventFilter(QObject *object, QEvent *event) -{ - Q_D(QQuickScrollView); - if (event->type() == QEvent::Wheel) { - d->setScrollBarsInteractive(true); - if (!d->wheelEnabled) - return true; - } - return QQuickPane::eventFilter(object, event); -} - -void QQuickScrollView::keyPressEvent(QKeyEvent *event) -{ - Q_D(QQuickScrollView); - QQuickPane::keyPressEvent(event); - switch (event->key()) { - case Qt::Key_Up: - if (QQuickScrollBar *vbar = d->verticalScrollBar()) { - vbar->decrease(); - event->accept(); - } - break; - case Qt::Key_Down: - if (QQuickScrollBar *vbar = d->verticalScrollBar()) { - vbar->increase(); - event->accept(); - } - break; - case Qt::Key_Left: - if (QQuickScrollBar *hbar = d->horizontalScrollBar()) { - hbar->decrease(); - event->accept(); - } - break; - case Qt::Key_Right: - if (QQuickScrollBar *hbar = d->horizontalScrollBar()) { - hbar->increase(); - event->accept(); - } - break; - default: - event->ignore(); - break; - } -} - -void QQuickScrollView::componentComplete() -{ - Q_D(QQuickScrollView); - QQuickPane::componentComplete(); - if (!d->contentItem) - d->ensureFlickable(true); -} - -void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) -{ - Q_D(QQuickScrollView); - if (newItem != d->flickable) { - // The new flickable was not created by us. In that case, we always - // assume/require that it has an explicit content size assigned. - d->flickableHasExplicitContentWidth = true; - d->flickableHasExplicitContentHeight = true; - auto newItemAsFlickable = qobject_cast<QQuickFlickable *>(newItem); - if (newItem && !newItemAsFlickable) - qmlWarning(this) << "ScrollView only supports Flickable types as its contentItem"; - d->setFlickable(newItemAsFlickable, false); - } - QQuickPane::contentItemChange(newItem, oldItem); -} - -void QQuickScrollView::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) -{ - Q_D(QQuickScrollView); - QQuickPane::contentSizeChange(newSize, oldSize); - if (d->flickable) { - // Only set the content size on the flickable if the flickable doesn't - // have an explicit assignment from before. Otherwise we can end up overwriting - // assignments done to those properties by the application. The - // exception is if the application has assigned a content size - // directly to the scrollview, which will then win even if the - // application has assigned something else to the flickable. - if (d->hasContentWidth || !d->flickableHasExplicitContentWidth) - d->flickable->setContentWidth(newSize.width()); - if (d->hasContentHeight || !d->flickableHasExplicitContentHeight) - d->flickable->setContentHeight(newSize.height()); - } -} - -#if QT_CONFIG(accessibility) -QAccessible::Role QQuickScrollView::accessibleRole() const -{ - return QAccessible::Pane; -} -#endif - -QT_END_NAMESPACE - -#include "moc_qquickscrollview_p.cpp" |