import qs.services import qs.config import QtQuick import QtQuick.Templates ScrollBar { id: root required property Flickable flickable property bool shouldBeActive property real nonAnimPosition property bool animating onHoveredChanged: { if (hovered) shouldBeActive = true; else shouldBeActive = flickable.moving; } onPositionChanged: { if (position === nonAnimPosition) animating = false; else if (!animating) nonAnimPosition = position; } position: nonAnimPosition implicitWidth: 5 contentItem: CustomRect { anchors.left: parent.left anchors.right: parent.right opacity: { if (root.size === 1) return 0; if (fullMouse.pressed) return 0.8; if (mouse.containsMouse) return 0.6; if (root.policy === ScrollBar.AlwaysOn || root.shouldBeActive) return 0.4; return 0; } radius: 1000 color: Config.colors.secondary MouseArea { id: mouse anchors.fill: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true acceptedButtons: Qt.NoButton } Behavior on opacity { Anim {} } } Connections { target: root.flickable function onMovingChanged(): void { if (root.flickable.moving) root.shouldBeActive = true; else hideDelay.restart(); } } Timer { id: hideDelay interval: 600 onTriggered: root.shouldBeActive = root.flickable.moving || root.hovered } CustomMouseArea { id: fullMouse anchors.fill: parent preventStealing: true onPressed: event => { root.animating = true; root.nonAnimPosition = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2)); } onPositionChanged: event => root.nonAnimPosition = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2)) function onWheel(event: WheelEvent): void { root.animating = true; if (event.angleDelta.y > 0) root.nonAnimPosition = Math.max(0, root.nonAnimPosition - 0.1); else if (event.angleDelta.y < 0) root.nonAnimPosition = Math.min(1 - root.size, root.nonAnimPosition + 0.1); } } Behavior on position { enabled: !fullMouse.pressed Anim {} } }