aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickscrollview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickscrollview.cpp')
-rw-r--r--src/quicktemplates2/qquickscrollview.cpp623
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"