103 lines
3.2 KiB
QML
103 lines
3.2 KiB
QML
// Copyright (C) 2021 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
import QtQuick
|
|
import Qt.labs.animation
|
|
|
|
Item {
|
|
id: root
|
|
objectName: "viewport"
|
|
default property alias data: __contentItem.data
|
|
property alias velocity: anim.velocity
|
|
property alias contentX: __contentItem.x // sign is reversed compared to Flickable.contentX
|
|
property alias contentY: __contentItem.y // sign is reversed compared to Flickable.contentY
|
|
property alias contentWidth: __contentItem.width
|
|
property alias contentHeight: __contentItem.height
|
|
signal flickStarted
|
|
signal flickEnded
|
|
|
|
Item {
|
|
id: __contentItem
|
|
objectName: "__contentItem"
|
|
width: childrenRect.width
|
|
height: childrenRect.height
|
|
|
|
BoundaryRule on x {
|
|
id: xbr
|
|
minimum: root.width - __contentItem.width
|
|
maximum: 0
|
|
minimumOvershoot: 100
|
|
maximumOvershoot: 100
|
|
overshootFilter: BoundaryRule.Peak
|
|
}
|
|
|
|
BoundaryRule on y {
|
|
id: ybr
|
|
minimum: root.height - __contentItem.height
|
|
maximum: 0
|
|
minimumOvershoot: 100
|
|
maximumOvershoot: 100
|
|
overshootFilter: BoundaryRule.Peak
|
|
}
|
|
|
|
DragHandler {
|
|
id: dragHandler
|
|
onActiveChanged:
|
|
if (active) {
|
|
anim.stop()
|
|
root.flickStarted()
|
|
} else {
|
|
var vel = centroid.velocity
|
|
if (xbr.returnToBounds())
|
|
vel.x = 0
|
|
if (ybr.returnToBounds())
|
|
vel.y = 0
|
|
if (vel.x !== 0 || vel.y !== 0)
|
|
anim.restart(vel)
|
|
else
|
|
root.flickEnded()
|
|
}
|
|
}
|
|
WheelHandler {
|
|
rotationScale: 15
|
|
property: "x"
|
|
orientation: Qt.Horizontal
|
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
onActiveChanged:
|
|
// emitting signals in both instances is redundant but hard to avoid
|
|
// when the touchpad is flicking along both axes
|
|
if (active) {
|
|
anim.stop()
|
|
root.flickStarted()
|
|
} else {
|
|
xbr.returnToBounds()
|
|
root.flickEnded()
|
|
}
|
|
}
|
|
WheelHandler {
|
|
rotationScale: 15
|
|
property: "y"
|
|
orientation: Qt.Vertical
|
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
onActiveChanged:
|
|
if (active) {
|
|
anim.stop()
|
|
root.flickStarted()
|
|
} else {
|
|
ybr.returnToBounds()
|
|
root.flickEnded()
|
|
}
|
|
}
|
|
MomentumAnimation {
|
|
id: anim
|
|
target: __contentItem
|
|
onStarted: root.flickStarted()
|
|
onStopped: {
|
|
xbr.returnToBounds()
|
|
ybr.returnToBounds()
|
|
root.flickEnded()
|
|
}
|
|
}
|
|
}
|
|
}
|