aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick/pointerhandlers/components/ScrollBar.qml
blob: d78ee56140a6e359b0ee83b12ae81c195e7bff3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

import QtQuick

Rectangle {
    id: root
    property real contentHeight: 100
    property FakeFlickable flick: null
    property real position

    onPositionChanged: if (flick && (drag.active || tap.active)) {
        if (knob.state === "horizontal")
            flick.contentX = position * knob.scrollDistance
        else if (knob.state === "vertical")
            flick.contentY = position * knob.scrollDistance
    }

    color: palette.button
    border.color: Qt.darker(palette.button, 1.5)
    gradient: Gradient {
        GradientStop { position: 0; color: Qt.darker(palette.button, 1.3) }
        GradientStop { position: 1; color: palette.button }
    }
    antialiasing: true
    radius: Math.min(width, height) / 6
    width: 20
    height: 20

    TapHandler {
        id: tap
        onTapped: {
            if (knob.state === "horizontal")
                knob.x = position.x - knob.width / 2
            else if (knob.state === "vertical")
                knob.y = position.y - knob.height / 2
        }
    }

    Rectangle {
        id: knob
        border.color: "black"
        border.width: 1
        gradient: Gradient {
            GradientStop { position: 0; color: palette.button }
            GradientStop { position: 1; color: Qt.darker(palette.button, 1.3) }
        }
        radius: 2
        antialiasing: true
        state: root.height > root.width ? "vertical" : root.height < root.width ? "horizontal" : ""
        property real scrollDistance: 0
        property real scrolledX: 0
        property real scrolledY: 0
        property real max: 0

        Binding on x {
            value: knob.scrolledX
            when: !drag.active
        }

        Binding on y {
            value: knob.scrolledY
            when: !drag.active
        }

        states: [
            // We will control the horizontal. We will control the vertical.
            State {
                name: "horizontal"
                PropertyChanges {
                    knob {
                        max: root.width - knob.width
                        scrolledX: Math.min(max, Math.max(0, max * flick.contentX / (flick.width - flick.contentWidth)))
                        scrolledY: 1
                        scrollDistance: flick.width - flick.contentWidth
                        width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2
                        height: root.height - 2
                    }
                    drag {
                        xAxis.minimum: 0
                        xAxis.maximum: knob.max
                        yAxis.minimum: 1
                        yAxis.maximum: 1
                    }
                    root.position: knob.x / drag.xAxis.maximum
                }
            },
            State {
                name: "vertical"
                PropertyChanges {
                    knob {
                        max: root.height - knob.height
                        scrolledX: 1
                        scrolledY: Math.min(max, Math.max(0, max * flick.contentY / (flick.height - flick.contentHeight)))
                        scrollDistance: flick.height - flick.contentHeight
                        width: root.width - 2
                        height: root.width - 2
                    }
                    drag {
                        xAxis.minimum: 1
                        xAxis.maximum: 1
                        yAxis.minimum: 0
                        yAxis.maximum: knob.max
                    }
                    root.position: knob.y / drag.yAxis.maximum
                }
            }
        ]

        DragHandler {
            id: drag
        }
    }
}