aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickswipedelegate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickswipedelegate.cpp')
-rw-r--r--src/quicktemplates2/qquickswipedelegate.cpp1527
1 files changed, 0 insertions, 1527 deletions
diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp
deleted file mode 100644
index 817704ba..00000000
--- a/src/quicktemplates2/qquickswipedelegate.cpp
+++ /dev/null
@@ -1,1527 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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 "qquickswipedelegate_p.h"
-#include "qquickswipedelegate_p_p.h"
-#include "qquickcontrol_p_p.h"
-#include "qquickitemdelegate_p_p.h"
-#include "qquickvelocitycalculator_p_p.h"
-
-#include <QtGui/qstylehints.h>
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/qpa/qplatformtheme.h>
-#include <QtQml/qqmlinfo.h>
-#include <QtQuick/private/qquickanimation_p.h>
-#include <QtQuick/private/qquicktransition_p.h>
-#include <QtQuick/private/qquicktransitionmanager_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype SwipeDelegate
- \inherits ItemDelegate
-//! \instantiates QQuickSwipeDelegate
- \inqmlmodule QtQuick.Controls
- \since 5.7
- \ingroup qtquickcontrols2-delegates
- \brief Swipable item delegate.
-
- SwipeDelegate presents a view item that can be swiped left or right to
- expose more options or information. It is used as a delegate in views such
- as \l ListView.
-
- In the following example, SwipeDelegate is used in a \l ListView to allow
- items to be removed from it by swiping to the left:
-
- \snippet qtquickcontrols2-swipedelegate.qml 1
-
- SwipeDelegate inherits its API from \l ItemDelegate, which is inherited
- from AbstractButton. For instance, you can set \l {AbstractButton::text}{text},
- and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton
- API.
-
- Information regarding the progress of a swipe, as well as the components
- that should be shown upon swiping, are both available through the
- \l {SwipeDelegate::}{swipe} grouped property object. For example,
- \c swipe.position holds the position of the
- swipe within the range \c -1.0 to \c 1.0. The \c swipe.left
- property determines which item will be displayed when the control is swiped
- to the right, and vice versa for \c swipe.right. The positioning of these
- components is left to applications to decide. For example, without specifying
- any position for \c swipe.left or \c swipe.right, the following will
- occur:
-
- \image qtquickcontrols2-swipedelegate.gif
-
- If \c swipe.left and \c swipe.right are anchored to the left and
- right of the \l {Control::}{background} item (respectively), they'll behave like this:
-
- \image qtquickcontrols2-swipedelegate-leading-trailing.gif
-
- When using \c swipe.left and \c swipe.right, the control cannot be
- swiped past the left and right edges. To achieve this type of "wrapping"
- behavior, set \c swipe.behind instead. This will result in the same
- item being shown regardless of which direction the control is swiped. For
- example, in the image below, we set \c swipe.behind and then swipe the
- control repeatedly in both directions:
-
- \image qtquickcontrols2-swipedelegate-behind.gif
-
- \sa {Customizing SwipeDelegate}, {Delegate Controls}, {Qt Quick Controls 2 - Swipe to Remove}{Swipe to Remove Example}
-*/
-
-namespace {
- typedef QQuickSwipeDelegateAttached Attached;
-
- Attached *attachedObject(QQuickItem *item) {
- return qobject_cast<Attached*>(qmlAttachedPropertiesObject<QQuickSwipeDelegate>(item, false));
- }
-
- enum PositionAnimation {
- DontAnimatePosition,
- AnimatePosition
- };
-}
-
-class QQuickSwipeTransitionManager : public QQuickTransitionManager
-{
-public:
- QQuickSwipeTransitionManager(QQuickSwipe *swipe);
-
- void transition(QQuickTransition *transition, qreal position);
-
-protected:
- void finished() override;
-
-private:
- QQuickSwipe *m_swipe = nullptr;
-};
-
-class QQuickSwipePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickSwipe)
-
-public:
- QQuickSwipePrivate(QQuickSwipeDelegate *control) : control(control) { }
-
- static QQuickSwipePrivate *get(QQuickSwipe *swipe);
-
- QQuickItem *createDelegateItem(QQmlComponent *component);
- QQuickItem *showRelevantItemForPosition(qreal position);
- QQuickItem *createRelevantItemForDistance(qreal distance);
- void reposition(PositionAnimation animationPolicy);
- void createLeftItem();
- void createBehindItem();
- void createRightItem();
- void createAndShowLeftItem();
- void createAndShowBehindItem();
- void createAndShowRightItem();
-
- void warnAboutMixingDelegates();
- void warnAboutSettingDelegatesWhileVisible();
-
- bool hasDelegates() const;
-
- bool isTransitioning() const;
- void beginTransition(qreal position);
- void finishTransition();
-
- QQuickSwipeDelegate *control = nullptr;
- // Same range as position, but is set before press events so that we can
- // keep track of which direction the user must swipe when using left and right delegates.
- qreal positionBeforePress = 0;
- qreal position = 0;
- // A "less strict" version of complete that is true if complete was true
- // before the last press event.
- bool wasComplete = false;
- bool complete = false;
- bool enabled = true;
- bool waitForTransition = false;
- QQuickVelocityCalculator velocityCalculator;
- QQmlComponent *left = nullptr;
- QQmlComponent *behind = nullptr;
- QQmlComponent *right = nullptr;
- QQuickItem *leftItem = nullptr;
- QQuickItem *behindItem = nullptr;
- QQuickItem *rightItem = nullptr;
- QQuickTransition *transition = nullptr;
- QScopedPointer<QQuickSwipeTransitionManager> transitionManager;
-};
-
-QQuickSwipeTransitionManager::QQuickSwipeTransitionManager(QQuickSwipe *swipe)
- : m_swipe(swipe)
-{
-}
-
-void QQuickSwipeTransitionManager::transition(QQuickTransition *transition, qreal position)
-{
- qmlExecuteDeferred(transition);
-
- QQmlProperty defaultTarget(m_swipe, QLatin1String("position"));
- QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations();
- const int count = animations.count(&animations);
- for (int i = 0; i < count; ++i) {
- QQuickAbstractAnimation *anim = animations.at(&animations, i);
- anim->setDefaultTarget(defaultTarget);
- }
-
- QList<QQuickStateAction> actions;
- actions << QQuickStateAction(m_swipe, QLatin1String("position"), position);
- QQuickTransitionManager::transition(actions, transition, m_swipe);
-}
-
-void QQuickSwipeTransitionManager::finished()
-{
- QQuickSwipePrivate::get(m_swipe)->finishTransition();
-}
-
-QQuickSwipePrivate *QQuickSwipePrivate::get(QQuickSwipe *swipe)
-{
- return swipe->d_func();
-}
-
-QQuickItem *QQuickSwipePrivate::createDelegateItem(QQmlComponent *component)
-{
- // If we don't use the correct context, it won't be possible to refer to
- // the control's id from within the delegates.
- QQmlContext *creationContext = component->creationContext();
- // The component might not have been created in QML, in which case
- // the creation context will be null and we have to create it ourselves.
- if (!creationContext)
- creationContext = qmlContext(control);
- QQmlContext *context = new QQmlContext(creationContext, control);
- context->setContextObject(control);
- QQuickItem *item = qobject_cast<QQuickItem*>(component->beginCreate(context));
- if (item) {
- item->setParentItem(control);
- component->completeCreate();
- }
- return item;
-}
-
-QQuickItem *QQuickSwipePrivate::showRelevantItemForPosition(qreal position)
-{
- if (qFuzzyIsNull(position))
- return nullptr;
-
- if (behind) {
- createAndShowBehindItem();
- return behindItem;
- }
-
- if (right && position < 0.0) {
- createAndShowRightItem();
- return rightItem;
- }
-
- if (left && position > 0.0) {
- createAndShowLeftItem();
- return leftItem;
- }
-
- return nullptr;
-}
-
-QQuickItem *QQuickSwipePrivate::createRelevantItemForDistance(qreal distance)
-{
- if (qFuzzyIsNull(distance))
- return nullptr;
-
- if (behind) {
- createBehindItem();
- return behindItem;
- }
-
- // a) If the position before the press was 0.0, we know that *any* movement
- // whose distance is negative will result in the right item being shown and
- // vice versa.
- // b) Once the control has been exposed (that is, swiped to the left or right,
- // and hence the position is either -1.0 or 1.0), we must use the width of the
- // relevant item to determine if the distance is larger than that item,
- // in order to know whether or not to display it.
- // c) If the control has been exposed, and the swipe is larger than the width
- // of the relevant item from which the swipe started from, we must show the
- // item on the other side (if any).
-
- if (right) {
- if ((distance < 0.0 && positionBeforePress == 0.0) /* a) */
- || (rightItem && positionBeforePress == -1.0 && distance < rightItem->width()) /* b) */
- || (leftItem && positionBeforePress == 1.0 && qAbs(distance) > leftItem->width())) /* c) */ {
- createRightItem();
- return rightItem;
- }
- }
-
- if (left) {
- if ((distance > 0.0 && positionBeforePress == 0.0) /* a) */
- || (leftItem && positionBeforePress == 1.0 && qAbs(distance) < leftItem->width()) /* b) */
- || (rightItem && positionBeforePress == -1.0 && qAbs(distance) > rightItem->width())) /* c) */ {
- createLeftItem();
- return leftItem;
- }
- }
-
- return nullptr;
-}
-
-void QQuickSwipePrivate::reposition(PositionAnimation animationPolicy)
-{
- QQuickItem *relevantItem = showRelevantItemForPosition(position);
- const qreal relevantWidth = relevantItem ? relevantItem->width() : 0.0;
- const qreal contentItemX = position * relevantWidth + control->leftPadding();
-
- // "Behavior on x" relies on the property system to know when it should update,
- // so we can prevent it from animating by setting the x position directly.
- if (animationPolicy == AnimatePosition) {
- if (QQuickItem *contentItem = control->contentItem())
- contentItem->setProperty("x", contentItemX);
- if (QQuickItem *background = control->background())
- background->setProperty("x", position * relevantWidth);
- } else {
- if (QQuickItem *contentItem = control->contentItem())
- contentItem->setX(contentItemX);
- if (QQuickItem *background = control->background())
- background->setX(position * relevantWidth);
- }
-}
-
-void QQuickSwipePrivate::createLeftItem()
-{
- if (!leftItem) {
- Q_Q(QQuickSwipe);
- q->setLeftItem(createDelegateItem(left));
- if (!leftItem)
- qmlWarning(control) << "Failed to create left item:" << left->errors();
- }
-}
-
-void QQuickSwipePrivate::createBehindItem()
-{
- if (!behindItem) {
- Q_Q(QQuickSwipe);
- q->setBehindItem(createDelegateItem(behind));
- if (!behindItem)
- qmlWarning(control) << "Failed to create behind item:" << behind->errors();
- }
-}
-
-void QQuickSwipePrivate::createRightItem()
-{
- if (!rightItem) {
- Q_Q(QQuickSwipe);
- q->setRightItem(createDelegateItem(right));
- if (!rightItem)
- qmlWarning(control) << "Failed to create right item:" << right->errors();
- }
-}
-
-void QQuickSwipePrivate::createAndShowLeftItem()
-{
- createLeftItem();
-
- if (leftItem)
- leftItem->setVisible(true);
-
- if (rightItem)
- rightItem->setVisible(false);
-}
-
-void QQuickSwipePrivate::createAndShowBehindItem()
-{
- createBehindItem();
-
- if (behindItem)
- behindItem->setVisible(true);
-}
-
-void QQuickSwipePrivate::createAndShowRightItem()
-{
- createRightItem();
-
- // This item may have already existed but was hidden.
- if (rightItem)
- rightItem->setVisible(true);
-
- // The left item isn't visible when the right item is visible, so save rendering effort by hiding it.
- if (leftItem)
- leftItem->setVisible(false);
-}
-
-void QQuickSwipePrivate::warnAboutMixingDelegates()
-{
- qmlWarning(control) << "cannot set both behind and left/right properties";
-}
-
-void QQuickSwipePrivate::warnAboutSettingDelegatesWhileVisible()
-{
- qmlWarning(control) << "left/right/behind properties may only be set when swipe.position is 0";
-}
-
-bool QQuickSwipePrivate::hasDelegates() const
-{
- return left || right || behind;
-}
-
-bool QQuickSwipePrivate::isTransitioning() const
-{
- return transitionManager && transitionManager->isRunning();
-}
-
-void QQuickSwipePrivate::beginTransition(qreal newPosition)
-{
- if (waitForTransition)
- return;
- Q_Q(QQuickSwipe);
- if (!transition) {
- q->setPosition(newPosition);
- finishTransition();
- return;
- }
-
- if (!transitionManager)
- transitionManager.reset(new QQuickSwipeTransitionManager(q));
-
- transitionManager->transition(transition, newPosition);
-}
-
-void QQuickSwipePrivate::finishTransition()
-{
- Q_Q(QQuickSwipe);
- waitForTransition = false;
- q->setComplete(qFuzzyCompare(qAbs(position), qreal(1.0)));
- if (complete) {
- emit q->opened();
- } else {
- if (qFuzzyIsNull(position))
- wasComplete = false;
- emit q->closed();
- }
-}
-
-QQuickSwipe::QQuickSwipe(QQuickSwipeDelegate *control)
- : QObject(*(new QQuickSwipePrivate(control)))
-{
-}
-
-QQmlComponent *QQuickSwipe::left() const
-{
- Q_D(const QQuickSwipe);
- return d->left;
-}
-
-void QQuickSwipe::setLeft(QQmlComponent *left)
-{
- Q_D(QQuickSwipe);
- if (left == d->left)
- return;
-
- if (d->behind) {
- d->warnAboutMixingDelegates();
- return;
- }
-
- if (!qFuzzyIsNull(d->position)) {
- d->warnAboutSettingDelegatesWhileVisible();
- return;
- }
-
- d->left = left;
-
- if (!d->left) {
- delete d->leftItem;
- d->leftItem = nullptr;
- }
-
- d->control->setFiltersChildMouseEvents(d->hasDelegates());
-
- emit leftChanged();
-}
-
-QQmlComponent *QQuickSwipe::behind() const
-{
- Q_D(const QQuickSwipe);
- return d->behind;
-}
-
-void QQuickSwipe::setBehind(QQmlComponent *behind)
-{
- Q_D(QQuickSwipe);
- if (behind == d->behind)
- return;
-
- if (d->left || d->right) {
- d->warnAboutMixingDelegates();
- return;
- }
-
- if (!qFuzzyIsNull(d->position)) {
- d->warnAboutSettingDelegatesWhileVisible();
- return;
- }
-
- d->behind = behind;
-
- if (!d->behind) {
- delete d->behindItem;
- d->behindItem = nullptr;
- }
-
- d->control->setFiltersChildMouseEvents(d->hasDelegates());
-
- emit behindChanged();
-}
-
-QQmlComponent *QQuickSwipe::right() const
-{
- Q_D(const QQuickSwipe);
- return d->right;
-}
-
-void QQuickSwipe::setRight(QQmlComponent *right)
-{
- Q_D(QQuickSwipe);
- if (right == d->right)
- return;
-
- if (d->behind) {
- d->warnAboutMixingDelegates();
- return;
- }
-
- if (!qFuzzyIsNull(d->position)) {
- d->warnAboutSettingDelegatesWhileVisible();
- return;
- }
-
- d->right = right;
-
- if (!d->right) {
- delete d->rightItem;
- d->rightItem = nullptr;
- }
-
- d->control->setFiltersChildMouseEvents(d->hasDelegates());
-
- emit rightChanged();
-}
-
-QQuickItem *QQuickSwipe::leftItem() const
-{
- Q_D(const QQuickSwipe);
- return d->leftItem;
-}
-
-void QQuickSwipe::setLeftItem(QQuickItem *item)
-{
- Q_D(QQuickSwipe);
- if (item == d->leftItem)
- return;
-
- delete d->leftItem;
- d->leftItem = item;
-
- if (d->leftItem) {
- d->leftItem->setParentItem(d->control);
-
- if (qFuzzyIsNull(d->leftItem->z()))
- d->leftItem->setZ(-2);
- }
-
- emit leftItemChanged();
-}
-
-QQuickItem *QQuickSwipe::behindItem() const
-{
- Q_D(const QQuickSwipe);
- return d->behindItem;
-}
-
-void QQuickSwipe::setBehindItem(QQuickItem *item)
-{
- Q_D(QQuickSwipe);
- if (item == d->behindItem)
- return;
-
- delete d->behindItem;
- d->behindItem = item;
-
- if (d->behindItem) {
- d->behindItem->setParentItem(d->control);
-
- if (qFuzzyIsNull(d->behindItem->z()))
- d->behindItem->setZ(-2);
- }
-
- emit behindItemChanged();
-}
-
-QQuickItem *QQuickSwipe::rightItem() const
-{
- Q_D(const QQuickSwipe);
- return d->rightItem;
-}
-
-void QQuickSwipe::setRightItem(QQuickItem *item)
-{
- Q_D(QQuickSwipe);
- if (item == d->rightItem)
- return;
-
- delete d->rightItem;
- d->rightItem = item;
-
- if (d->rightItem) {
- d->rightItem->setParentItem(d->control);
-
- if (qFuzzyIsNull(d->rightItem->z()))
- d->rightItem->setZ(-2);
- }
-
- emit rightItemChanged();
-}
-
-qreal QQuickSwipe::position() const
-{
- Q_D(const QQuickSwipe);
- return d->position;
-}
-
-void QQuickSwipe::setPosition(qreal position)
-{
- Q_D(QQuickSwipe);
- const qreal adjustedPosition = qBound<qreal>(-1.0, position, 1.0);
- if (adjustedPosition == d->position)
- return;
-
- d->position = adjustedPosition;
- d->reposition(AnimatePosition);
- emit positionChanged();
-}
-
-bool QQuickSwipe::isComplete() const
-{
- Q_D(const QQuickSwipe);
- return d->complete;
-}
-
-void QQuickSwipe::setComplete(bool complete)
-{
- Q_D(QQuickSwipe);
- if (complete == d->complete)
- return;
-
- d->complete = complete;
- emit completeChanged();
- if (d->complete)
- emit completed();
-}
-
-bool QQuickSwipe::isEnabled() const
-{
- Q_D(const QQuickSwipe);
- return d->enabled;
-}
-
-void QQuickSwipe::setEnabled(bool enabled)
-{
- Q_D(QQuickSwipe);
- if (enabled == d->enabled)
- return;
-
- d->enabled = enabled;
- emit enabledChanged();
-}
-
-QQuickTransition *QQuickSwipe::transition() const
-{
- Q_D(const QQuickSwipe);
- return d->transition;
-}
-
-void QQuickSwipe::setTransition(QQuickTransition *transition)
-{
- Q_D(QQuickSwipe);
- if (transition == d->transition)
- return;
-
- d->transition = transition;
- emit transitionChanged();
-}
-
-void QQuickSwipe::open(QQuickSwipeDelegate::Side side)
-{
- Q_D(QQuickSwipe);
- if (qFuzzyCompare(qAbs(d->position), qreal(1.0)))
- return;
-
- if ((side != QQuickSwipeDelegate::Left && side != QQuickSwipeDelegate::Right)
- || (!d->left && !d->behind && side == QQuickSwipeDelegate::Left)
- || (!d->right && !d->behind && side == QQuickSwipeDelegate::Right))
- return;
-
- d->beginTransition(side);
- d->wasComplete = true;
- d->velocityCalculator.reset();
- d->positionBeforePress = d->position;
-}
-
-void QQuickSwipe::close()
-{
- Q_D(QQuickSwipe);
- if (qFuzzyIsNull(d->position))
- return;
-
- if (d->control->isPressed()) {
- // We don't support closing when we're pressed; release() or clicked() should be used instead.
- return;
- }
-
- d->beginTransition(0.0);
- d->waitForTransition = true;
- d->wasComplete = false;
- d->positionBeforePress = 0.0;
- d->velocityCalculator.reset();
-}
-
-QQuickSwipeDelegatePrivate::QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control)
- : swipe(control)
-{
-}
-
-void QQuickSwipeDelegatePrivate::resizeBackground()
-{
- if (!background)
- return;
-
- resizingBackground = true;
-
- QQuickItemPrivate *p = QQuickItemPrivate::get(background);
- const bool extraAllocated = extra.isAllocated();
- // Don't check for or set the x here since it will just be overwritten by reposition().
- if (((!p->widthValid() || !extraAllocated || !extra->hasBackgroundWidth))
- || (extraAllocated && (extra->hasLeftInset || extra->hasRightInset))) {
- background->setWidth(width - getLeftInset() - getRightInset());
- }
- if (((!p->heightValid() || !extraAllocated || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y()))
- || (extraAllocated && (extra->hasTopInset || extra->hasBottomInset))) {
- background->setY(getTopInset());
- background->setHeight(height - getTopInset() - getBottomInset());
- }
-
- resizingBackground = false;
-}
-
-bool QQuickSwipeDelegatePrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event)
-{
- Q_Q(QQuickSwipeDelegate);
- const auto posInItem = item->mapToItem(q, event->position().toPoint());
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe);
- // If the position is 0, we want to handle events ourselves - we don't want child items to steal them.
- // This code will only get called when a child item has been created;
- // events will go through the regular channels (mousePressEvent()) until then.
- if (qFuzzyIsNull(swipePrivate->position)) {
- q->mousePressEvent(event);
- // The press point could be incorrect if the press happened over a child item,
- // so we correct it after calling the base class' mousePressEvent(), rather
- // than having to duplicate its code just so we can set the pressPoint.
- setPressPoint(posInItem);
- return true;
- }
-
- // If the delegate is swiped open, send the event to the exposed item,
- // in case it's an interactive child (like a Button).
- if (swipePrivate->complete)
- forwardMouseEvent(event, item, posInItem);
-
- // The position is non-zero, this press could be either for a delegate or the control itself
- // (the control can be clicked to e.g. close the swipe). Either way, we must begin measuring
- // mouse movement in case it turns into a swipe, in which case we grab the mouse.
- swipePrivate->positionBeforePress = swipePrivate->position;
- swipePrivate->velocityCalculator.startMeasuring(event->position().toPoint(), event->timestamp());
- setPressPoint(item->mapToItem(q, event->position().toPoint()));
-
- // When a delegate or any of its children uses the attached properties and signals,
- // it declares that it wants mouse events.
- const bool delivered = attachedObjectsSetPressed(item, event->scenePosition(), true);
- if (delivered)
- event->accept();
- return delivered;
-}
-
-bool QQuickSwipeDelegatePrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event)
-{
- Q_Q(QQuickSwipeDelegate);
-
- if (holdTimer > 0) {
- if (QLineF(pressPoint, event->position()).length() > QGuiApplication::styleHints()->startDragDistance())
- stopPressAndHold();
- }
-
- // The delegate can still be pressed when swipe.enabled is false,
- // but the mouse moving shouldn't have any effect on swipe.position.
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe);
- if (!swipePrivate->enabled)
- return false;
-
- // Protect against division by zero.
- if (width == 0)
- return false;
-
- // Don't bother reacting to events if we don't have any delegates.
- if (!swipePrivate->left && !swipePrivate->right && !swipePrivate->behind)
- return false;
-
- // Don't handle move events for the control if it wasn't pressed.
- if (item == q && !pressed)
- return false;
-
- const QPointF mappedEventPos = item->mapToItem(q, event->position().toPoint());
- const qreal distance = (mappedEventPos - pressPoint).x();
- if (!q->keepMouseGrab()) {
- // We used to use the custom threshold that QQuickDrawerPrivate::grabMouse used,
- // but since it's larger than what Flickable uses, it results in Flickable
- // stealing events from us (QTBUG-50045), so now we use the default.
- const bool overThreshold = QQuickWindowPrivate::dragOverThreshold(distance, Qt::XAxis, event);
- if (window && overThreshold) {
- QQuickItem *grabber = q->window()->mouseGrabberItem();
- if (!grabber || !grabber->keepMouseGrab()) {
- q->grabMouse();
- q->setKeepMouseGrab(true);
- q->setPressed(true);
- swipe.setComplete(false);
-
- attachedObjectsSetPressed(item, event->scenePosition(), false, true);
- }
- }
- }
-
- if (q->keepMouseGrab()) {
- // Ensure we don't try to calculate a position when the user tried to drag
- // to the left when the left item is already exposed, and vice versa.
- // The code below assumes that the drag is valid, so if we don't have this check,
- // the wrong items are visible and the swiping wraps.
- if (swipePrivate->behind
- || ((swipePrivate->left || swipePrivate->right)
- && (qFuzzyIsNull(swipePrivate->positionBeforePress)
- || (swipePrivate->positionBeforePress == -1.0 && distance >= 0.0)
- || (swipePrivate->positionBeforePress == 1.0 && distance <= 0.0)))) {
-
- // We must instantiate the items here so that we can calculate the
- // position against the width of the relevant item.
- QQuickItem *relevantItem = swipePrivate->createRelevantItemForDistance(distance);
- // If there isn't any relevant item, the user may have swiped back to the 0 position,
- // or they swiped back to a position that is equal to positionBeforePress.
- const qreal normalizedDistance = relevantItem ? distance / relevantItem->width() : 0.0;
- qreal position = 0;
-
- // If the control was exposed before the drag begun, the distance should be inverted.
- // For example, if the control had been swiped to the right, the position would be 1.0.
- // If the control was then swiped to the left by a distance of -20 pixels, the normalized
- // distance might be -0.2, for example, which cannot be used as the position; the swipe
- // started from the right, so we account for that by adding the position.
- if (qFuzzyIsNull(normalizedDistance)) {
- // There are two cases when the normalizedDistance can be 0,
- // and we must distinguish between them:
- //
- // a) The swipe returns to the position that it was at before the press event.
- // In this case, the distance will be 0.
- // There would have been many position changes in the meantime, so we can't just
- // ignore the move event; we have to set position to what it was before the press.
- //
- // b) If the position was at, 1.0, for example, and the control was then swiped
- // to the left by the exact width of the left item, there won't be any relevant item
- // (because the swipe's position would be at 0.0). In turn, the normalizedDistance
- // would be 0 (because of the lack of a relevant item), but the distance will be non-zero.
- position = qFuzzyIsNull(distance) ? swipePrivate->positionBeforePress : 0;
- } else if (!swipePrivate->wasComplete) {
- position = normalizedDistance;
- } else {
- position = distance > 0 ? normalizedDistance - 1.0 : normalizedDistance + 1.0;
- }
-
- if (swipePrivate->isTransitioning())
- swipePrivate->transitionManager->cancel();
- swipe.setPosition(position);
- }
- } else {
- // The swipe wasn't initiated.
- if (event->position().toPoint().y() < 0 || event->position().toPoint().y() > height) {
- // The mouse went outside the vertical bounds of the control, so
- // we should no longer consider it pressed.
- q->setPressed(false);
- }
- }
-
- event->accept();
-
- return q->keepMouseGrab();
-}
-
-static const qreal exposeVelocityThreshold = 300.0;
-
-bool QQuickSwipeDelegatePrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event)
-{
- Q_Q(QQuickSwipeDelegate);
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe);
- swipePrivate->velocityCalculator.stopMeasuring(event->position().toPoint(), event->timestamp());
-
- const bool hadGrabbedMouse = q->keepMouseGrab();
- q->setKeepMouseGrab(false);
-
- // QQuickSwipe::close() doesn't allow closing while pressed, but now we're releasing.
- // So set the pressed state false if this release _could_ result in closing, so that check can be bypassed.
- if (!qIsNull(swipePrivate->position))
- q->setPressed(false);
-
- // Animations for the background and contentItem delegates are typically
- // only enabled when !control.down, so that the animations aren't running
- // when the user is swiping. To ensure that the animations are enabled
- // *before* the positions of these delegates change (via the swipe.setPosition() calls below),
- // we must cancel the press. QQuickAbstractButton::mouseUngrabEvent() does this
- // for us, but by then it's too late.
- if (hadGrabbedMouse) {
- // TODO: this is copied from QQuickAbstractButton::mouseUngrabEvent().
- // Eventually it should be moved into a private helper so that we don't have to duplicate it.
- q->setPressed(false);
- stopPressRepeat();
- stopPressAndHold();
- emit q->canceled();
- }
-
- // Inform the given item that the mouse is released, in case it's an interactive child.
- if (item != q && (swipePrivate->complete || swipePrivate->wasComplete))
- forwardMouseEvent(event, item, item->mapFromScene(event->scenePosition()));
-
- // The control can be exposed by either swiping past the halfway mark, or swiping fast enough.
- const qreal swipeVelocity = swipePrivate->velocityCalculator.velocity().x();
- if (swipePrivate->position > 0.5 ||
- (swipePrivate->position > 0.0 && swipeVelocity > exposeVelocityThreshold)) {
- swipePrivate->beginTransition(1.0);
- swipePrivate->wasComplete = true;
- } else if (swipePrivate->position < -0.5 ||
- (swipePrivate->position < 0.0 && swipeVelocity < -exposeVelocityThreshold)) {
- swipePrivate->beginTransition(-1.0);
- swipePrivate->wasComplete = true;
- } else if (!swipePrivate->isTransitioning()) {
- // The position is either <= 0.5 or >= -0.5, so the position should go to 0.
- // However, if the position was already 0 or close to it, we were just clicked,
- // and we don't need to start a transition.
- if (!qFuzzyIsNull(swipePrivate->position))
- swipePrivate->beginTransition(0.0);
- swipePrivate->wasComplete = false;
- }
-
- // Inform any QQuickSwipeDelegateAttached objects that the mouse is released.
- attachedObjectsSetPressed(item, event->scenePosition(), false);
-
- // Only consume child events if we had grabbed the mouse.
- return hadGrabbedMouse;
-}
-
-/*! \internal
- Send a localized copy of \a event with \a localPos to the \a destination item.
-*/
-void QQuickSwipeDelegatePrivate::forwardMouseEvent(QMouseEvent *event, QQuickItem *destination, QPointF localPos)
-{
- Q_Q(QQuickSwipeDelegate);
- QMutableSinglePointEvent localizedEvent(*event);
- localizedEvent.mutablePoint().setPosition(localPos);
- QGuiApplication::sendEvent(destination, &localizedEvent);
- q->setPressed(!localizedEvent.isAccepted());
-}
-
-/*! \internal
- For each QQuickSwipeDelegateAttached object on children of \a item:
- if \a scenePos is in the attachee (the item to which it's attached), then
- set its \a pressed state. Unless \a cancel is \c true, when the state
- transitions from pressed to released, also emit \l QQuickSwipeDelegateAttached::clicked().
- Returns \c true if at least one relevant attached object was found.
-*/
-bool QQuickSwipeDelegatePrivate::attachedObjectsSetPressed(QQuickItem *item, QPointF scenePos, bool pressed, bool cancel)
-{
- bool found = false;
- QVarLengthArray<QQuickItem *, 16> itemAndChildren;
- itemAndChildren.append(item);
- for (int i = 0; i < itemAndChildren.count(); ++i) {
- auto item = itemAndChildren.at(i);
- auto posInItem = item->mapFromScene(scenePos);
- if (item->contains(posInItem)) {
- if (Attached *attached = attachedObject(item)) {
- const bool wasPressed = attached->isPressed();
- attached->setPressed(pressed);
- if (wasPressed && !pressed && !cancel)
- emit attached->clicked();
- found = true;
- }
- }
- for (auto child : item->childItems())
- itemAndChildren.append(child);
- }
- return found;
-}
-
-static void warnIfHorizontallyAnchored(QQuickItem *item, const QString &itemName)
-{
- if (!item)
- return;
-
- QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors;
- if (anchors && (anchors->fill() || anchors->centerIn() || anchors->left().item || anchors->right().item)
- && !item->property("_q_QQuickSwipeDelegate_warned").toBool()) {
- qmlWarning(item) << QString::fromLatin1("SwipeDelegate: cannot use horizontal anchors with %1; unable to layout the item.").arg(itemName);
- item->setProperty("_q_QQuickSwipeDelegate_warned", true);
- }
-}
-
-void QQuickSwipeDelegatePrivate::resizeContent()
-{
- warnIfHorizontallyAnchored(background, QStringLiteral("background"));
- warnIfHorizontallyAnchored(contentItem, QStringLiteral("contentItem"));
-
- // If the background and contentItem are repositioned due to a swipe,
- // we don't want to call QQuickControlPrivate's implementation of this function,
- // as it repositions the contentItem to be visible.
- // However, we still want to position the contentItem vertically
- // and resize it (in case the control was resized while open).
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe);
- if (!swipePrivate->complete) {
- QQuickItemDelegatePrivate::resizeContent();
- } else if (contentItem) {
- Q_Q(QQuickSwipeDelegate);
- contentItem->setY(q->topPadding());
- contentItem->setWidth(q->availableWidth());
- contentItem->setHeight(q->availableHeight());
- }
-}
-
-QPalette QQuickSwipeDelegatePrivate::defaultPalette() const
-{
- return QQuickTheme::palette(QQuickTheme::ListView);
-}
-
-QQuickSwipeDelegate::QQuickSwipeDelegate(QQuickItem *parent)
- : QQuickItemDelegate(*(new QQuickSwipeDelegatePrivate(this)), parent)
-{
- // QQuickSwipeDelegate still depends on synthesized mouse events
- setAcceptTouchEvents(false);
-}
-
-/*!
- \since QtQuick.Controls 2.2 (Qt 5.9)
- \qmlmethod void QtQuick.Controls::SwipeDelegate::swipe.open(enumeration side)
-
- This method sets the \c position of the swipe so that it opens
- from the specified \a side.
-
- Available values:
- \value SwipeDelegate.Left The \c position is set to \c 1, which makes the swipe open
- from the left. Either \c swipe.left or \c swipe.behind must
- have been specified; otherwise the call is ignored.
- \value SwipeDelegate.Right The \c position is set to \c -1, which makes the swipe open
- from the right. Either \c swipe.right or \c swipe.behind must
- have been specified; otherwise the call is ignored.
-
- Any animations defined for the \l {Item::}{x} position of \l {Control::}{contentItem}
- and \l {Control::}{background} will be triggered.
-
- \sa swipe, swipe.close()
-*/
-
-/*!
- \since QtQuick.Controls 2.1 (Qt 5.8)
- \qmlmethod void QtQuick.Controls::SwipeDelegate::swipe.close()
-
- This method sets the \c position of the swipe to \c 0. Any animations
- defined for the \l {Item::}{x} position of \l {Control::}{contentItem}
- and \l {Control::}{background} will be triggered.
-
- \sa swipe, swipe.open()
-*/
-
-/*!
- \since QtQuick.Controls 2.2 (Qt 5.9)
- \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.opened()
-
- This signal is emitted when the delegate has been swiped open
- and the transition has finished.
-
- It is useful for performing some action upon completion of a swipe.
- For example, it can be used to remove the delegate from the list
- that it is in.
-
- \sa swipe, swipe.closed()
-*/
-
-/*!
- \since QtQuick.Controls 2.2 (Qt 5.9)
- \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.closed()
-
- This signal is emitted when the delegate has been swiped to closed
- and the transition has finished.
-
- It is useful for performing some action upon cancellation of a swipe.
- For example, it can be used to cancel the removal of the delegate from
- the list that it is in.
-
- \sa swipe, swipe.opened()
-*/
-
-/*!
- \since QtQuick.Controls 2.1 (Qt 5.8)
- \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.completed()
-
- This signal is emitted when \c swipe.complete becomes \c true.
-
- It is useful for performing some action upon completion of a swipe.
- For example, it can be used to remove the delegate from the list
- that it is in.
-
- \sa swipe
-*/
-
-/*!
- \qmlproperty real QtQuick.Controls::SwipeDelegate::swipe.position
- \qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.complete
- \qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.enabled
- \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.left
- \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.behind
- \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.right
- \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.leftItem
- \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.behindItem
- \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.rightItem
- \qmlproperty Transition QtQuick.Controls::SwipeDelegate::swipe.transition
-
- \table
- \header
- \li Name
- \li Description
- \row
- \li position
- \li This read-only property holds the position of the swipe relative to either
- side of the control. When this value reaches either
- \c -1.0 (left side) or \c 1.0 (right side) and the mouse button is
- released, \c complete will be \c true.
- \row
- \li complete
- \li This read-only property holds whether the control is fully exposed after
- having been swiped to the left or right.
-
- When complete is \c true, any interactive items declared in \c left,
- \c right, or \c behind will receive mouse events.
- \row
- \li enabled
- \li This property determines whether or not the control can be swiped.
-
- This property was added in QtQuick.Controls 2.2.
- \row
- \li left
- \li This property holds the left delegate.
-
- The left delegate sits behind both \l {Control::}{contentItem} and
- \l {Control::}{background}. When the SwipeDelegate is swiped to the right,
- this item will be gradually revealed.
-
- \include qquickswipedelegate-interaction.qdocinc
- \row
- \li behind
- \li This property holds the delegate that is shown when the
- SwipeDelegate is swiped to both the left and right.
-
- As with the \c left and \c right delegates, it sits behind both
- \l {Control::}{contentItem} and \l {Control::}{background}. However, a
- SwipeDelegate whose \c behind has been set can be continuously swiped
- from either side, and will always show the same item.
-
- \include qquickswipedelegate-interaction.qdocinc
- \row
- \li right
- \li This property holds the right delegate.
-
- The right delegate sits behind both \l {Control::}{contentItem} and
- \l {Control::}{background}. When the SwipeDelegate is swiped to the left,
- this item will be gradually revealed.
-
- \include qquickswipedelegate-interaction.qdocinc
- \row
- \li leftItem
- \li This read-only property holds the item instantiated from the \c left component.
-
- If \c left has not been set, or the position hasn't changed since
- creation of the SwipeDelegate, this property will be \c null.
- \row
- \li behindItem
- \li This read-only property holds the item instantiated from the \c behind component.
-
- If \c behind has not been set, or the position hasn't changed since
- creation of the SwipeDelegate, this property will be \c null.
- \row
- \li rightItem
- \li This read-only property holds the item instantiated from the \c right component.
-
- If \c right has not been set, or the position hasn't changed since
- creation of the SwipeDelegate, this property will be \c null.
- \row
- \li transition
- \li This property holds the transition that is applied when a swipe is released,
- or \l swipe.open() or \l swipe.close() is called.
-
- \snippet qtquickcontrols2-swipedelegate-transition.qml 1
-
- This property was added in Qt Quick Controls 2.2.
- \endtable
-
- \sa {Control::}{contentItem}, {Control::}{background}, swipe.open(), swipe.close()
-*/
-QQuickSwipe *QQuickSwipeDelegate::swipe() const
-{
- Q_D(const QQuickSwipeDelegate);
- return const_cast<QQuickSwipe*>(&d->swipe);
-}
-
-QQuickSwipeDelegateAttached *QQuickSwipeDelegate::qmlAttachedProperties(QObject *object)
-{
- return new QQuickSwipeDelegateAttached(object);
-}
-
-static bool isChildOrGrandchildOf(QQuickItem *child, QQuickItem *item)
-{
- return item && (child == item || item->isAncestorOf(child));
-}
-
-bool QQuickSwipeDelegate::childMouseEventFilter(QQuickItem *child, QEvent *event)
-{
- Q_D(QQuickSwipeDelegate);
- // The contentItem is, by default, usually a non-interactive item like Text, and
- // the same applies to the background. This means that simply stacking the left/right/behind
- // items before these items won't allow us to get mouse events when the control is not currently exposed
- // but has been previously. Therefore, we instead call setFiltersChildMouseEvents(true) in the constructor
- // and filter out child events only when the child is the left/right/behind item.
- const QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe);
- if (!isChildOrGrandchildOf(child, swipePrivate->leftItem) && !isChildOrGrandchildOf(child, swipePrivate->behindItem)
- && !isChildOrGrandchildOf(child, swipePrivate->rightItem)) {
- return false;
- }
-
- switch (event->type()) {
- case QEvent::MouseButtonPress: {
- return d->handleMousePressEvent(child, static_cast<QMouseEvent *>(event));
- } case QEvent::MouseMove: {
- return d->handleMouseMoveEvent(child, static_cast<QMouseEvent *>(event));
- } case QEvent::MouseButtonRelease: {
- // Make sure that the control gets release events if it has created child
- // items that are stealing events from it.
- QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- QQuickItemDelegate::mouseReleaseEvent(mouseEvent);
- return d->handleMouseReleaseEvent(child, mouseEvent);
- } case QEvent::UngrabMouse: {
- // If the mouse was pressed over e.g. rightItem and then dragged down,
- // the ListView would eventually grab the mouse, at which point we must
- // clear the pressed flag so that it doesn't stay pressed after the release.
- Attached *attached = attachedObject(child);
- if (attached)
- attached->setPressed(false);
- return false;
- } default:
- return false;
- }
-}
-
-// We only override this to set positionBeforePress;
-// otherwise, it's the same as the base class implementation.
-void QQuickSwipeDelegate::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QQuickSwipeDelegate);
- QQuickItemDelegate::mousePressEvent(event);
-
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe);
- if (!swipePrivate->enabled)
- return;
-
- swipePrivate->positionBeforePress = swipePrivate->position;
- swipePrivate->velocityCalculator.startMeasuring(event->position().toPoint(), event->timestamp());
-
- if (swipePrivate->complete) {
- auto item = d->swipe.rightItem();
- if (item && item->contains(item->mapFromScene(event->scenePosition()))) {
- d->pressedItem = item;
- d->handleMousePressEvent(item, event);
- } else {
- item = d->swipe.leftItem();
- if (item && item->contains(item->mapFromScene(event->scenePosition()))) {
- d->pressedItem = item;
- d->handleMousePressEvent(item, event);
- }
- }
- }
-}
-
-void QQuickSwipeDelegate::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QQuickSwipeDelegate);
- if (filtersChildMouseEvents())
- d->handleMouseMoveEvent(this, event);
- else
- QQuickItemDelegate::mouseMoveEvent(event);
- if (d->pressedItem)
- d->handleMouseMoveEvent(d->pressedItem, event);
-}
-
-void QQuickSwipeDelegate::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickSwipeDelegate);
- if (!filtersChildMouseEvents() || !d->handleMouseReleaseEvent(this, event))
- QQuickItemDelegate::mouseReleaseEvent(event);
-
- if (d->pressedItem) {
- if (d->pressedItem->acceptedMouseButtons())
- d->handleMouseReleaseEvent(d->pressedItem, event);
- d->pressedItem = nullptr;
- }
-}
-
-void QQuickSwipeDelegate::mouseUngrabEvent()
-{
- Q_D(QQuickSwipeDelegate);
- setPressed(false);
-
- auto item = d->swipe.rightItem();
- if (item) {
- if (auto control = qmlobject_cast<QQuickControl *>(item))
- QQuickControlPrivate::get(control)->handleUngrab();
- Attached *attached = attachedObject(item);
- if (attached)
- attached->setPressed(false);
- } else {
- item = d->swipe.leftItem();
- if (item) {
- if (auto control = qmlobject_cast<QQuickControl *>(item))
- QQuickControlPrivate::get(control)->handleUngrab();
- Attached *attached = attachedObject(item);
- if (attached)
- attached->setPressed(false);
- }
- }
-
- d->pressedItem = nullptr;
-}
-
-void QQuickSwipeDelegate::touchEvent(QTouchEvent *event)
-{
- // Don't allow QQuickControl accept the touch event, because QQuickSwipeDelegate
- // is still based on synthesized mouse events
- event->ignore();
-}
-
-void QQuickSwipeDelegate::componentComplete()
-{
- Q_D(QQuickSwipeDelegate);
- QQuickItemDelegate::componentComplete();
- QQuickSwipePrivate::get(&d->swipe)->reposition(DontAnimatePosition);
-}
-
-void QQuickSwipeDelegate::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickSwipeDelegate);
- QQuickControl::geometryChange(newGeometry, oldGeometry);
-
- if (isComponentComplete() && !qFuzzyCompare(newGeometry.width(), oldGeometry.width())) {
- QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe);
- swipePrivate->reposition(DontAnimatePosition);
- }
-}
-
-QFont QQuickSwipeDelegate::defaultFont() const
-{
- return QQuickTheme::font(QQuickTheme::ListView);
-}
-
-#if QT_CONFIG(accessibility)
-QAccessible::Role QQuickSwipeDelegate::accessibleRole() const
-{
- return QAccessible::ListItem;
-}
-#endif
-
-class QQuickSwipeDelegateAttachedPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickSwipeDelegateAttached)
-
-public:
- // True when left/right/behind is non-interactive and is pressed.
- bool pressed = false;
-};
-
-/*!
- \since QtQuick.Controls 2.1 (Qt 5.8)
- \qmlattachedsignal QtQuick.Controls::SwipeDelegate::clicked()
-
- This signal can be attached to a non-interactive item declared in
- \c swipe.left, \c swipe.right, or \c swipe.behind, in order to react to
- clicks. Items can only be clicked when \c swipe.complete is \c true.
-
- For interactive controls (such as \l Button) declared in these
- items, use their respective \c clicked() signal instead.
-
- To respond to clicks on the SwipeDelegate itself, use its
- \l {AbstractButton::}{clicked()} signal.
-
- \note See the documentation for \l pressed for information on
- how to use the event-related properties correctly.
-
- \sa pressed
-*/
-
-QQuickSwipeDelegateAttached::QQuickSwipeDelegateAttached(QObject *object)
- : QObject(*(new QQuickSwipeDelegateAttachedPrivate), object)
-{
- QQuickItem *item = qobject_cast<QQuickItem *>(object);
- if (item) {
- // This allows us to be notified when an otherwise non-interactive item
- // is pressed and clicked. The alternative is much more more complex:
- // iterating through children that contain the event pos and finding
- // the first one with an attached object.
- item->setAcceptedMouseButtons(Qt::AllButtons);
- } else {
- qWarning() << "Attached properties of SwipeDelegate must be accessed through an Item";
- }
-}
-
-/*!
- \since QtQuick.Controls 2.1 (Qt 5.8)
- \qmlattachedproperty bool QtQuick.Controls::SwipeDelegate::pressed
- \readonly
-
- This property can be attached to a non-interactive item declared in
- \c swipe.left, \c swipe.right, or \c swipe.behind, in order to detect if it
- is pressed. Items can only be pressed when \c swipe.complete is \c true.
-
- For example:
-
- \code
- swipe.right: Label {
- anchors.right: parent.right
- height: parent.height
- text: "Action"
- color: "white"
- padding: 12
- background: Rectangle {
- color: SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
- }
- }
- \endcode
-
- It is possible to have multiple items which individually receive mouse and
- touch events. For example, to have two actions in the \c swipe.right item,
- use the following code:
-
- \code
- swipe.right: Row {
- anchors.right: parent.right
- height: parent.height
-
- Label {
- id: moveLabel
- text: qsTr("Move")
- color: "white"
- verticalAlignment: Label.AlignVCenter
- padding: 12
- height: parent.height
-
- SwipeDelegate.onClicked: console.log("Moving...")
-
- background: Rectangle {
- color: moveLabel.SwipeDelegate.pressed ? Qt.darker("#ffbf47", 1.1) : "#ffbf47"
- }
- }
- Label {
- id: deleteLabel
- text: qsTr("Delete")
- color: "white"
- verticalAlignment: Label.AlignVCenter
- padding: 12
- height: parent.height
-
- SwipeDelegate.onClicked: console.log("Deleting...")
-
- background: Rectangle {
- color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
- }
- }
- }
- \endcode
-
- Note how the \c color assignment in each \l {Control::}{background} item
- qualifies the attached property with the \c id of the label. This
- is important; using the attached properties on an item causes that item
- to accept events. Suppose we had left out the \c id in the previous example:
-
- \code
- color: SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
- \endcode
-
- The \l Rectangle background item is a child of the label, so it naturally
- receives events before it. In practice, this means that the background
- color will change, but the \c onClicked handler in the label will never
- get called.
-
- For interactive controls (such as \l Button) declared in these
- items, use their respective \c pressed property instead.
-
- For presses on the SwipeDelegate itself, use its
- \l {AbstractButton::}{pressed} property.
-
- \sa clicked()
-*/
-bool QQuickSwipeDelegateAttached::isPressed() const
-{
- Q_D(const QQuickSwipeDelegateAttached);
- return d->pressed;
-}
-
-void QQuickSwipeDelegateAttached::setPressed(bool pressed)
-{
- Q_D(QQuickSwipeDelegateAttached);
- if (pressed == d->pressed)
- return;
-
- d->pressed = pressed;
- emit pressedChanged();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qquickswipe_p.cpp"
-#include "moc_qquickswipedelegate_p.cpp"