import QtQuick import QtQuick.Controls import QtQuick.Templates as T import qs.Constants T.ScrollView { id: root property color handleColor: Qt.alpha(Color.mTertiary, 0.8) property color handleHoverColor: handleColor property color handlePressedColor: handleColor property color trackColor: Color.transparent property real handleWidth: 6 property real handleRadius: Style.radiusM property int verticalPolicy: ScrollBar.AsNeeded property int horizontalPolicy: ScrollBar.AsNeeded property bool preventHorizontalScroll: horizontalPolicy === ScrollBar.AlwaysOff property int boundsBehavior: Flickable.StopAtBounds property int flickableDirection: Flickable.VerticalFlick // Function to configure the underlying Flickable function configureFlickable() { // Find the internal Flickable (it's usually the first child) for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.toString().indexOf("Flickable") !== -1) { // Configure the flickable to prevent horizontal scrolling child.boundsBehavior = root.boundsBehavior; if (root.preventHorizontalScroll) { child.flickableDirection = Flickable.VerticalFlick; child.contentWidth = Qt.binding(() => { return child.width; }); } else { child.flickableDirection = root.flickableDirection; } break; } } } implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) // Configure the internal flickable when it becomes available Component.onCompleted: { configureFlickable(); } // Watch for changes in horizontalPolicy onHorizontalPolicyChanged: { preventHorizontalScroll = (horizontalPolicy === ScrollBar.AlwaysOff); configureFlickable(); } ScrollBar.vertical: ScrollBar { parent: root x: root.mirrored ? 0 : root.width - width y: root.topPadding height: root.availableHeight active: root.ScrollBar.horizontal.active policy: root.verticalPolicy contentItem: Rectangle { implicitWidth: root.handleWidth implicitHeight: 100 radius: root.handleRadius color: parent.pressed ? root.handlePressedColor : parent.hovered ? root.handleHoverColor : root.handleColor opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1 : 0 Behavior on opacity { NumberAnimation { duration: Style.animationFast } } Behavior on color { ColorAnimation { duration: Style.animationFast } } } background: Rectangle { implicitWidth: root.handleWidth implicitHeight: 100 color: root.trackColor opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0 radius: root.handleRadius / 2 Behavior on opacity { NumberAnimation { duration: Style.animationFast } } } } ScrollBar.horizontal: ScrollBar { parent: root x: root.leftPadding y: root.height - height width: root.availableWidth active: root.ScrollBar.vertical.active policy: root.horizontalPolicy contentItem: Rectangle { implicitWidth: 100 implicitHeight: root.handleWidth radius: root.handleRadius color: parent.pressed ? root.handlePressedColor : parent.hovered ? root.handleHoverColor : root.handleColor opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1 : 0 Behavior on opacity { NumberAnimation { duration: Style.animationFast } } Behavior on color { ColorAnimation { duration: Style.animationFast } } } background: Rectangle { implicitWidth: 100 implicitHeight: root.handleWidth color: root.trackColor opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0 radius: root.handleRadius / 2 Behavior on opacity { NumberAnimation { duration: Style.animationFast } } } } }