Fix & improve keyboard and mousewheel flicking

This commit is contained in:
miruka 2019-12-10 11:49:46 -04:00
parent 2eadaff542
commit ad6f111793
5 changed files with 61 additions and 45 deletions

View File

@ -1,6 +1,4 @@
- make pageup/down not slippery again
- better cancel for all boxes - better cancel for all boxes
- get rid of all currentSpacing stuff
- Media - Media
- Handle set avatar upload errors - Handle set avatar upload errors
@ -24,6 +22,7 @@
- Refactoring - Refactoring
- Use a singleton for utils.js - Use a singleton for utils.js
- Use HBox for Profile - Use HBox for Profile
- Get rid of all `currentSpacing` stuff
- Banners - Banners
- Composer - Composer
- Try gel for the models and stop being lazy in python - Try gel for the models and stop being lazy in python

View File

@ -3,7 +3,7 @@ import QtQuick.Controls 2.12
ListView { ListView {
id: listView id: listView
interactive: enableFlicking interactive: allowDragging
currentIndex: -1 currentIndex: -1
keyNavigationWraps: true keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration highlightMoveDuration: theme.animationDuration
@ -15,18 +15,13 @@ ListView {
maximumFlickVelocity: 4000 maximumFlickVelocity: 4000
property bool enableFlicking: true
readonly property int currentItemHeight:
currentItem ? currentItem.height : 0
highlight: Rectangle { highlight: Rectangle {
color: theme.controls.listView.highlight color: theme.controls.listView.highlight
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
visible: listView.interactive || ! listView.enableFlicking visible: listView.interactive || ! listView.allowDragging
} }
add: Transition { add: Transition {
@ -52,4 +47,32 @@ ListView {
} }
displaced: move displaced: move
property bool allowDragging: true
property alias cursorShape: mouseArea.cursorShape
readonly property int currentItemHeight:
currentItem ? currentItem.height : 0
Connections {
target: listView
enabled: ! listView.allowDragging
// interactive gets temporarily set to true below to allow wheel scroll
onDraggingChanged: listView.interactive = false
}
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: ! parent.allowDragging || cursorShape !== Qt.ArrowCursor
acceptedButtons: Qt.NoButton
onWheel: {
// Allow wheel usage, will be back to false on any drag attempt
parent.interactive = true
wheel.accepted = false
}
}
} }

View File

@ -61,7 +61,7 @@ Rectangle {
HListView { HListView {
id: eventList id: eventList
clip: true clip: true
enableFlicking: false allowDragging: false
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: theme.spacing anchors.leftMargin: theme.spacing
@ -92,8 +92,6 @@ Rectangle {
property bool ownEventsOnRight: property bool ownEventsOnRight:
width < theme.chat.eventList.ownEventsOnRightUnderWidth width < theme.chat.eventList.ownEventsOnRightUnderWidth
property alias cursorShape: mouseArea.cursorShape
function canCombine(item, itemAfter) { function canCombine(item, itemAfter) {
if (! item || ! itemAfter) return false if (! item || ! itemAfter) return false
@ -160,19 +158,6 @@ Rectangle {
} }
delegate: EventDelegate {} delegate: EventDelegate {}
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
onWheel: Utils.smartVerticalFlick(
eventList,
200 * Qt.styleHints.wheelScrollLines *
(wheel.angleDelta.y < 0 ? 1 : -1),
2,
)
}
} }
} }

View File

@ -72,32 +72,25 @@ Item {
HShortcut { HShortcut {
enabled: toFlick enabled: toFlick
sequences: settings.keys.scrollUp sequences: settings.keys.scrollUp
onActivated: Utils.smartVerticalFlick(toFlick, -335) onActivated: Utils.flickPages(toFlick, -1 / 10)
} }
HShortcut { HShortcut {
enabled: toFlick enabled: toFlick
sequences: settings.keys.scrollDown sequences: settings.keys.scrollDown
onActivated: Utils.smartVerticalFlick(toFlick, 335) onActivated: Utils.flickPages(toFlick, 1 / 10)
} }
HShortcut { HShortcut {
enabled: toFlick enabled: toFlick
sequences: settings.keys.scrollPageUp sequences: settings.keys.scrollPageUp
onActivated: Utils.smartVerticalFlick( onActivated: Utils.flickPages(toFlick, -1)
toFlick, -2.3 * toFlick.height, 8,
)
// Ensure only a slight slip after releasing the key
// onReleased: Utils.smartVerticalFlick(toFlick, -335)
} }
HShortcut { HShortcut {
enabled: toFlick enabled: toFlick
sequences: settings.keys.scrollPageDown sequences: settings.keys.scrollPageDown
onActivated: Utils.smartVerticalFlick( onActivated: Utils.flickPages(toFlick, 1)
toFlick, 2.3 * toFlick.height, 8,
)
// onReleased: Utils.smartVerticalFlick(toFlick, 335)
} }
HShortcut { HShortcut {

View File

@ -229,20 +229,36 @@ function getItem(array, mainKey, value) {
} }
function smartVerticalFlick(flickable, baseVelocity, fastMultiply=4) { function flickPages(flickable, pages) {
if (! flickable.interactive && flickable.enableFlicking) return // Adapt velocity and deceleration for the number of pages to flick.
// If this is a repeated flicking, flick faster than a single flick.
if (! flickable.interactive && flickable.allowDragging) return
baseVelocity = -baseVelocity const futureVelocity = -flickable.height * pages
let vel = -flickable.verticalVelocity const currentVelocity = -flickable.verticalVelocity
let fast = (baseVelocity < 0 && vel < baseVelocity / 2) || const goFaster =
(baseVelocity > 0 && vel > baseVelocity / 2) (futureVelocity < 0 && currentVelocity < futureVelocity / 2) ||
(futureVelocity > 0 && currentVelocity > futureVelocity / 2)
flickable.flick(0, baseVelocity * (fast ? fastMultiply : 1)) const normalDecel = flickable.flickDeceleration
const fastMultiply = pages && 8 / (1 - Math.log10(Math.abs(pages)))
const magicNumber = 2.5
flickable.flickDeceleration = Math.max(
goFaster ? normalDecel : -Infinity,
Math.abs(normalDecel * magicNumber * pages),
)
flickable.flick(
0, futureVelocity * magicNumber * (goFaster ? fastMultiply : 1),
)
flickable.flickDeceleration = normalDecel
} }
function flickToTop(flickable) { function flickToTop(flickable) {
if (! flickable.interactive && flickable.enableFlicking) return if (! flickable.interactive && flickable.allowDragging) return
if (flickable.visibleArea.yPosition < 0) return if (flickable.visibleArea.yPosition < 0) return
flickable.contentY -= flickable.contentHeight flickable.contentY -= flickable.contentHeight
@ -252,7 +268,7 @@ function flickToTop(flickable) {
function flickToBottom(flickable) { function flickToBottom(flickable) {
if (! flickable.interactive && flickable.enableFlicking) return if (! flickable.interactive && flickable.allowDragging) return
if (flickable.visibleArea.yPosition < 0) return if (flickable.visibleArea.yPosition < 0) return
flickable.contentY = flickTarget.contentHeight - flickTarget.height flickable.contentY = flickTarget.contentHeight - flickTarget.height