aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickscrollindicator.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2016-04-13 15:59:53 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2016-04-13 15:28:11 +0000
commita60c8e60d508117ddf48876b44d31e6d5ab98da6 (patch)
tree8bf008a1bf8dc34338450eee86d2b55e84cba36c /src/quicktemplates2/qquickscrollindicator.cpp
parente719087dce50d739c723c5ef9af2a9226318aa02 (diff)
Templates: rename the C++ module to qtquicktemplates2
Change-Id: I146da903b46f5c2caf865e37291c25376b49021a Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src/quicktemplates2/qquickscrollindicator.cpp')
-rw-r--r--src/quicktemplates2/qquickscrollindicator.cpp429
1 files changed, 429 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquickscrollindicator.cpp b/src/quicktemplates2/qquickscrollindicator.cpp
new file mode 100644
index 00000000..619c9b4b
--- /dev/null
+++ b/src/quicktemplates2/qquickscrollindicator.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Templates 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 "qquickscrollindicator_p.h"
+#include "qquickcontrol_p_p.h"
+
+#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype ScrollIndicator
+ \inherits Control
+ \instantiates QQuickScrollIndicator
+ \inqmlmodule Qt.labs.controls
+ \ingroup qtquickcontrols2-indicators
+ \brief A non-interactive scroll indicator control.
+
+ ScrollIndicator is a non-interactive indicator that indicates the current scroll
+ position. A scroll indicator can be either \l vertical or \l horizontal, and can
+ be attached to any \l Flickable, such as \l ListView and \l GridView.
+
+ \image qtquickcontrols-scrollindicator.png
+
+ \code
+ Flickable {
+ // ...
+ ScrollIndicator.vertical: ScrollIndicator { }
+ }
+ \endcode
+
+ \note When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically}
+ or \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, its geometry and
+ the following properties are automatically set and updated as appropriate:
+ \list
+ \li \l orientation
+ \li \l position
+ \li \l size
+ \li \l active
+ \endlist
+
+ Horizontal and vertical scroll indicators do not share the \l active state with
+ each other by default. In order to keep both indicators visible whilst scrolling
+ to either direction, establish a two-way binding between the active states as
+ presented by the following example:
+
+ \snippet qtquickcontrols-scrollindicator-active.qml 1
+
+ \labs
+
+ \sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls}
+*/
+
+class QQuickScrollIndicatorPrivate : public QQuickControlPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickScrollIndicator)
+
+public:
+ QQuickScrollIndicatorPrivate() : size(0), position(0),
+ active(false), orientation(Qt::Vertical)
+ {
+ }
+
+ void resizeContent() override;
+
+ qreal size;
+ qreal position;
+ bool active;
+ Qt::Orientation orientation;
+};
+
+void QQuickScrollIndicatorPrivate::resizeContent()
+{
+ Q_Q(QQuickScrollIndicator);
+ if (!contentItem)
+ return;
+
+ if (orientation == Qt::Horizontal) {
+ contentItem->setPosition(QPointF(q->leftPadding() + position * q->availableWidth(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth() * size, q->availableHeight()));
+ } else {
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + position * q->availableHeight()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * size));
+ }
+}
+
+QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent) :
+ QQuickControl(*(new QQuickScrollIndicatorPrivate), parent)
+{
+}
+
+QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object)
+{
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object);
+ if (flickable)
+ return new QQuickScrollIndicatorAttached(flickable);
+
+ qWarning() << "ScrollIndicator must be attached to a Flickable" << object;
+ return nullptr;
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::ScrollIndicator::size
+
+ This property holds the size of the indicator, scaled to \c {0.0 - 1.0}.
+
+ \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea}
+*/
+qreal QQuickScrollIndicator::size() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->size;
+}
+
+void QQuickScrollIndicator::setSize(qreal size)
+{
+ Q_D(QQuickScrollIndicator);
+ if (qFuzzyCompare(d->size, size))
+ return;
+
+ d->size = size;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit sizeChanged();
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::ScrollIndicator::position
+
+ This property holds the position of the indicator, scaled to \c {0.0 - 1.0}.
+
+ \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea}
+*/
+qreal QQuickScrollIndicator::position() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->position;
+}
+
+void QQuickScrollIndicator::setPosition(qreal position)
+{
+ Q_D(QQuickScrollIndicator);
+ if (qFuzzyCompare(d->position, position))
+ return;
+
+ d->position = position;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit positionChanged();
+}
+
+/*!
+ \qmlproperty bool Qt.labs.controls::ScrollIndicator::active
+
+ This property holds whether the indicator is active, that is, when the
+ attached Flickable is \l {Flickable::moving}{moving}.
+*/
+bool QQuickScrollIndicator::isActive() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->active;
+}
+
+void QQuickScrollIndicator::setActive(bool active)
+{
+ Q_D(QQuickScrollIndicator);
+ if (d->active == active)
+ return;
+
+ d->active = active;
+ emit activeChanged();
+}
+
+/*!
+ \qmlproperty enumeration Qt.labs.controls::ScrollIndicator::orientation
+
+ This property holds the orientation of the indicator.
+
+ Possible values:
+ \value Qt.Horizontal Horizontal
+ \value Qt.Vertical Vertical (default)
+*/
+Qt::Orientation QQuickScrollIndicator::orientation() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->orientation;
+}
+
+void QQuickScrollIndicator::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QQuickScrollIndicator);
+ if (d->orientation == orientation)
+ return;
+
+ d->orientation = orientation;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit orientationChanged();
+}
+
+class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+{
+public:
+ QQuickScrollIndicatorAttachedPrivate(QQuickFlickable *flickable) : flickable(flickable), horizontal(nullptr), vertical(nullptr) { }
+
+ void activateHorizontal();
+ void activateVertical();
+
+ void layoutHorizontal(bool move = true);
+ void layoutVertical(bool move = true);
+
+ void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
+ QQuickFlickable *flickable;
+ QQuickScrollIndicator *horizontal;
+ QQuickScrollIndicator *vertical;
+};
+
+void QQuickScrollIndicatorAttachedPrivate::activateHorizontal()
+{
+ horizontal->setActive(flickable->isMovingHorizontally());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::activateVertical()
+{
+ vertical->setActive(flickable->isMovingVertically());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
+{
+ Q_ASSERT(horizontal && flickable);
+ horizontal->setWidth(flickable->width());
+ if (move)
+ horizontal->setY(flickable->height() - horizontal->height());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move)
+{
+ Q_ASSERT(vertical && flickable);
+ vertical->setHeight(flickable->height());
+ if (move && !QQuickItemPrivate::get(vertical)->isMirrored())
+ vertical->setX(flickable->width() - vertical->width());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_UNUSED(item);
+ Q_UNUSED(newGeometry);
+ if (horizontal && horizontal->height() > 0) {
+ bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height());
+ layoutHorizontal(move);
+ }
+ if (vertical && vertical->width() > 0) {
+ bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width());
+ layoutVertical(move);
+ }
+}
+
+QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QQuickFlickable *flickable) :
+ QObject(*(new QQuickScrollIndicatorAttachedPrivate(flickable)), flickable)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(flickable);
+ p->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange);
+}
+
+QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached()
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->horizontal)
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ if (d->vertical)
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+}
+
+/*!
+ \qmlattachedproperty ScrollIndicator Qt.labs.controls::ScrollIndicator::horizontal
+
+ This property attaches a horizontal scroll indicator to a \l Flickable.
+
+ \code
+ Flickable {
+ contentWidth: 2000
+ ScrollIndicator.horizontal: ScrollIndicator { }
+ }
+ \endcode
+*/
+QQuickScrollIndicator *QQuickScrollIndicatorAttached::horizontal() const
+{
+ Q_D(const QQuickScrollIndicatorAttached);
+ return d->horizontal;
+}
+
+void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizontal)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->horizontal == horizontal)
+ return;
+
+ if (d->horizontal) {
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal)));
+ disconnect(area, SIGNAL(xPositionChanged(qreal)), d->horizontal, SLOT(setPosition(qreal)));
+ }
+
+ d->horizontal = horizontal;
+
+ if (horizontal) {
+ if (!horizontal->parentItem())
+ horizontal->setParentItem(d->flickable);
+ horizontal->setOrientation(Qt::Horizontal);
+
+ QQuickItemPrivate::get(horizontal)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange);
+ QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
+ connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
+
+ d->layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+ }
+ emit horizontalChanged();
+}
+
+/*!
+ \qmlattachedproperty ScrollIndicator Qt.labs.controls::ScrollIndicator::vertical
+
+ This property attaches a vertical scroll indicator to a \l Flickable.
+
+ \code
+ Flickable {
+ contentHeight: 2000
+ ScrollIndicator.vertical: ScrollIndicator { }
+ }
+ \endcode
+*/
+QQuickScrollIndicator *QQuickScrollIndicatorAttached::vertical() const
+{
+ Q_D(const QQuickScrollIndicatorAttached);
+ return d->vertical;
+}
+
+void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->vertical == vertical)
+ return;
+
+ if (d->vertical) {
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal)));
+ disconnect(area, SIGNAL(yPositionChanged(qreal)), d->vertical, SLOT(setPosition(qreal)));
+ }
+
+ d->vertical = vertical;
+
+ if (vertical) {
+ if (!vertical->parentItem())
+ vertical->setParentItem(d->flickable);
+ vertical->setOrientation(Qt::Vertical);
+
+ QQuickItemPrivate::get(vertical)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange);
+ QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
+ connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
+
+ d->layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+ }
+ emit verticalChanged();
+}
+
+#ifndef QT_NO_ACCESSIBILITY
+QAccessible::Role QQuickScrollIndicator::accessibleRole() const
+{
+ return QAccessible::Indicator;
+}
+#endif
+
+QT_END_NAMESPACE