diff --git a/imports/Spectral/Component/ScrollHelper.qml b/imports/Spectral/Component/ScrollHelper.qml new file mode 100644 index 0000000..a611527 --- /dev/null +++ b/imports/Spectral/Component/ScrollHelper.qml @@ -0,0 +1,89 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.2 + +MouseArea { + id: root + propagateComposedEvents: true + + property Flickable flickable + + //Place the mouse area under the flickable + z: -1 + onFlickableChanged: { + flickable.interactive = false + flickable.maximumFlickVelocity = 100000 + flickable.boundsBehavior = Flickable.StopAtBounds + root.parent = flickable + } + + function scrollByPixelDelta(flickableItem, pixelDelta) { + if (!pixelDelta) { + return flickableItem.contentY; + } + + var minYExtent = flickableItem.originY + flickableItem.topMargin; + var maxYExtent = (flickableItem.contentHeight + flickableItem.bottomMargin + flickableItem.originY) - flickableItem.height; + + if (typeof(flickableItem.headerItem) !== "undefined" && flickableItem.headerItem) { + minYExtent += flickableItem.headerItem.height + } + + //Avoid overscrolling + return Math.max(minYExtent, Math.min(maxYExtent, flickableItem.contentY - pixelDelta)); + } + + function calculateNewPosition(flickableItem, wheel) { + //Nothing to scroll + if (flickableItem.contentHeight < flickableItem.height) { + return flickableItem.contentY; + } + //Ignore 0 events (happens at least with Christians trackpad) + if (wheel.pixelDelta.y == 0 && wheel.angleDelta.y == 0) { + return flickableItem.contentY; + } + //pixelDelta seems to be the same as angleDelta/8 + var pixelDelta = 0 + //The pixelDelta is a smaller number if both are provided, so pixelDelta can be 0 while angleDelta is still something. So we check the angleDelta + if (wheel.angleDelta.y) { + var wheelScrollLines = 3 //Default value of QApplication wheelScrollLines property + var pixelPerLine = 20 //Default value in Qt, originally comes from QTextEdit + var ticks = (wheel.angleDelta.y / 8) / 15.0 //Divide by 8 gives us pixels typically come in 15pixel steps. + pixelDelta = ticks * pixelPerLine * wheelScrollLines + } else { + pixelDelta = wheel.pixelDelta.y + } + + return scrollByPixelDelta(flickableItem, pixelDelta); + } + + function scrollDown() { + flickable.flick(0, 0); + flickable.contentY = scrollByPixelDelta(flickable, -60); //3 lines * 20 pixels + } + + function scrollUp() { + flickable.flick(0, 0); + flickable.contentY = scrollByPixelDelta(flickable, 60); //3 lines * 20 pixels + } + + onWheel: { + var newPos = calculateNewPosition(flickable, wheel); + // console.warn("Delta: ", wheel.pixelDelta.y); + // console.warn("Old position: ", flickable.contentY); + // console.warn("New position: ", newPos); + + // Show the scrollbars + flickable.flick(0, 0); + flickable.contentY = newPos; + cancelFlickStateTimer.start() + } + + + Timer { + id: cancelFlickStateTimer + //How long the scrollbar will remain visible + interval: 500 + // Hide the scrollbars + onTriggered: flickable.cancelFlick(); + } +} diff --git a/imports/Spectral/Component/qmldir b/imports/Spectral/Component/qmldir index edf7d5c..90ce0ea 100644 --- a/imports/Spectral/Component/qmldir +++ b/imports/Spectral/Component/qmldir @@ -5,3 +5,4 @@ SideNavButton 2.0 SideNavButton.qml AutoImage 2.0 AutoImage.qml AutoLabel 2.0 AutoLabel.qml AutoTextArea 2.0 AutoTextArea.qml +ScrollHelper 2.0 ScrollHelper.qml diff --git a/imports/Spectral/Panel/RoomListDelegate.qml b/imports/Spectral/Panel/RoomListDelegate.qml index f1759d5..00177cf 100644 --- a/imports/Spectral/Panel/RoomListDelegate.qml +++ b/imports/Spectral/Panel/RoomListDelegate.qml @@ -9,8 +9,6 @@ import Spectral.Setting 0.1 import Spectral.Component 2.0 Rectangle { - readonly property bool highlighted: currentRoom === enteredRoom - color: MSettings.darkTheme ? "#303030" : "#fafafa" AutoMouseArea { @@ -38,13 +36,13 @@ Rectangle { Rectangle { anchors.fill: parent - visible: highlightCount > 0 || highlighted + visible: highlightCount > 0 || currentRoom === enteredRoom color: Material.accent opacity: 0.1 } Rectangle { - width: unreadCount > 0 || highlighted ? 4 : 0 + width: unreadCount > 0 ? 4 : 0 height: parent.height color: Material.accent diff --git a/imports/Spectral/Panel/RoomListPanelForm.ui.qml b/imports/Spectral/Panel/RoomListPanelForm.ui.qml index 7d43f0e..3b555de 100644 --- a/imports/Spectral/Panel/RoomListPanelForm.ui.qml +++ b/imports/Spectral/Panel/RoomListPanelForm.ui.qml @@ -102,6 +102,7 @@ Rectangle { spacing: 1 clip: true + interactive: false model: roomListProxyModel @@ -136,6 +137,12 @@ Rectangle { } RoomContextMenu { id: roomContextMenu } + + ScrollHelper { + anchors.fill: parent + + flickable: parent + } } } } diff --git a/imports/Spectral/Panel/RoomPanelForm.ui.qml b/imports/Spectral/Panel/RoomPanelForm.ui.qml index 00c6725..42a8506 100644 --- a/imports/Spectral/Panel/RoomPanelForm.ui.qml +++ b/imports/Spectral/Panel/RoomPanelForm.ui.qml @@ -77,6 +77,7 @@ Item { displayMarginEnd: 40 verticalLayoutDirection: ListView.BottomToTop spacing: 8 + interactive: false boundsBehavior: Flickable.DragOverBounds @@ -156,6 +157,12 @@ Item { } } + ScrollHelper { + anchors.fill: parent + + flickable: parent + } + RoundButton { width: 64 height: 64 diff --git a/res.qrc b/res.qrc index 2bd1e2c..f0cd070 100644 --- a/res.qrc +++ b/res.qrc @@ -51,5 +51,6 @@ imports/Spectral/Component/AutoImage.qml imports/Spectral/Component/AutoLabel.qml imports/Spectral/Component/AutoTextArea.qml + imports/Spectral/Component/ScrollHelper.qml