diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-07-14 00:02:33 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-07-15 20:12:04 +0200 |
commit | 142cfea2ee8b50b5ef2e22b9de4fe4c461411ff2 (patch) | |
tree | e0bd0bcb6d3325a2ee5d9c2984f3cd5ff78cb425 | |
parent | 89d62446608feb3296edb692b218d9eecdb24fe4 (diff) | |
download | kube-142cfea2ee8b50b5ef2e22b9de4fe4c461411ff2.tar.gz kube-142cfea2ee8b50b5ef2e22b9de4fe4c461411ff2.zip |
Use a ScrollHelper to fix scrolling on listviews
Because the standard scrolling is so unusable depending on the input
device we replace it by something custom that is fairly similar to what
QQC1 ScrollView did. Using a ScrollView sucks in many ways, including
that you have to wrap all sorts of things which is just code wise not
great at all. The ScrollHelper can instead be attached to any existing
flickable to override it's scrolling behaviour, so we can also silently
drop it once the default flickable behaviour starts to make sense.
-rw-r--r-- | framework/qml/ListView.qml | 29 | ||||
-rw-r--r-- | framework/qml/ScrollHelper.qml | 96 | ||||
-rw-r--r-- | framework/qmldir | 1 |
3 files changed, 100 insertions, 26 deletions
diff --git a/framework/qml/ListView.qml b/framework/qml/ListView.qml index f137d03e..161fe48e 100644 --- a/framework/qml/ListView.qml +++ b/framework/qml/ListView.qml | |||
@@ -19,37 +19,14 @@ | |||
19 | 19 | ||
20 | import QtQuick 2.7 | 20 | import QtQuick 2.7 |
21 | import QtQuick.Controls 2 | 21 | import QtQuick.Controls 2 |
22 | import org.kube.framework 1.0 as Kube | ||
22 | 23 | ||
23 | ListView { | 24 | ListView { |
24 | id: root | 25 | id: root |
25 | property var focusProxy: root | ||
26 | 26 | ||
27 | /* | 27 | Kube.ScrollHelper { |
28 | * The MouseArea + interactive: false + maximumFlickVelocity are required | 28 | flickable: root |
29 | * to fix scrolling for desktop systems where we don't want flicking behaviour. | ||
30 | * | ||
31 | * See also: | ||
32 | * ScrollView.qml in qtquickcontrols | ||
33 | * qquickwheelarea.cpp in qtquickcontrols | ||
34 | */ | ||
35 | MouseArea { | ||
36 | anchors.fill: root | 29 | anchors.fill: root |
37 | propagateComposedEvents: true | ||
38 | |||
39 | onWheel: { | ||
40 | //Some trackpads (mine) emit 0 events in between that we can safely ignore. | ||
41 | if (wheel.pixelDelta.y) { | ||
42 | //120 is apparently the factor used in windows(https://chromium.googlesource.com/chromium/src/+/70763eb93a32555910a3b4269aeec51252ab9ec6/ui/events/event.cc) | ||
43 | listView.flick(0, wheel.pixelDelta.y * 120) | ||
44 | } else if (wheel.angleDelta.y) { | ||
45 | //Arbitrary but this seems to work for me... | ||
46 | listView.flick(0, wheel.angleDelta.y * 10) | ||
47 | } | ||
48 | } | ||
49 | } | 30 | } |
50 | interactive: false | ||
51 | maximumFlickVelocity: 100000 | ||
52 | |||
53 | boundsBehavior: Flickable.StopAtBounds | ||
54 | } | 31 | } |
55 | 32 | ||
diff --git a/framework/qml/ScrollHelper.qml b/framework/qml/ScrollHelper.qml new file mode 100644 index 00000000..b2f91201 --- /dev/null +++ b/framework/qml/ScrollHelper.qml | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsystems.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtQuick.Controls 2 | ||
22 | import org.kube.framework 1.0 as Kube | ||
23 | |||
24 | /* | ||
25 | * The MouseArea + interactive: false + maximumFlickVelocity are required | ||
26 | * to fix scrolling for desktop systems where we don't want flicking behaviour. | ||
27 | * | ||
28 | * See also: | ||
29 | * ScrollView.qml in qtquickcontrols | ||
30 | * qquickwheelarea.cpp in qtquickcontrols | ||
31 | */ | ||
32 | MouseArea { | ||
33 | id: root | ||
34 | propagateComposedEvents: true | ||
35 | |||
36 | property Flickable flickable | ||
37 | |||
38 | //Place the mouse area under the flickable | ||
39 | z: -1 | ||
40 | onFlickableChanged: { | ||
41 | flickable.interactive = false | ||
42 | flickable.maximumFlickVelocity = 100000 | ||
43 | flickable.boundsBehavior = Flickable.StopAtBounds | ||
44 | root.parent = flickable | ||
45 | } | ||
46 | |||
47 | function calculateNewPosition(flickableItem, wheel) { | ||
48 | //Nothing to scroll | ||
49 | if (flickableItem.contentHeight < flickableItem.height) { | ||
50 | return flickableItem.contentY; | ||
51 | } | ||
52 | //Ignore 0 events (happens at least with Christians trackpad) | ||
53 | if (wheel.pixelDelta.y == 0 && wheel.angleDelta.y == 0) { | ||
54 | return flickableItem.contentY; | ||
55 | } | ||
56 | //pixelDelta seems to be the same as angleDelta/8 | ||
57 | var pixelDelta = wheel.pixelDelta.y != 0 ? wheel.pixelDelta.y : wheel.angleDelta.y / 8 | ||
58 | |||
59 | var y = pixelDelta | ||
60 | if (!y) { | ||
61 | return flickableItem.contentY; | ||
62 | } | ||
63 | |||
64 | var minYExtent = flickableItem.originY + flickableItem.topMargin; | ||
65 | var maxYExtent = (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY) - flickableItem.height; | ||
66 | |||
67 | if (typeof(flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) { | ||
68 | minYExtent += flickableItem.headerItem.height | ||
69 | } | ||
70 | |||
71 | //Avoid overscrolling | ||
72 | return Math.max(minYExtent, Math.min(maxYExtent, flickableItem.contentY - y)); | ||
73 | } | ||
74 | |||
75 | onWheel: { | ||
76 | var newPos = calculateNewPosition(flickable, wheel); | ||
77 | // console.warn("Delta: ", wheel.pixelDelta.y); | ||
78 | // console.warn("Old position: ", flickable.contentY); | ||
79 | // console.warn("New position: ", newPos); | ||
80 | |||
81 | // Show the scrollbars | ||
82 | flickable.flick(0, 0); | ||
83 | flickable.contentY = newPos; | ||
84 | cancelFlickStateTimer.start() | ||
85 | } | ||
86 | |||
87 | |||
88 | Timer { | ||
89 | id: cancelFlickStateTimer | ||
90 | //How long the scrollbar will remain visible | ||
91 | interval: 500 | ||
92 | // Hide the scrollbars | ||
93 | onTriggered: listView.cancelFlick(); | ||
94 | } | ||
95 | } | ||
96 | |||
diff --git a/framework/qmldir b/framework/qmldir index b8e7345f..04893ec9 100644 --- a/framework/qmldir +++ b/framework/qmldir | |||
@@ -30,6 +30,7 @@ View 1.0 View.qml | |||
30 | AutocompleteLineEdit 1.0 AutocompleteLineEdit.qml | 30 | AutocompleteLineEdit 1.0 AutocompleteLineEdit.qml |
31 | AttachmentDelegate 1.0 AttachmentDelegate.qml | 31 | AttachmentDelegate 1.0 AttachmentDelegate.qml |
32 | ListView 1.0 ListView.qml | 32 | ListView 1.0 ListView.qml |
33 | ScrollHelper 1.0 ScrollHelper.qml | ||
33 | singleton Messages 1.0 Messages.qml | 34 | singleton Messages 1.0 Messages.qml |
34 | singleton Colors 1.0 Colors.qml | 35 | singleton Colors 1.0 Colors.qml |
35 | singleton Icons 1.0 Icons.qml | 36 | singleton Icons 1.0 Icons.qml |