Files
pay/desktop/widgets/ScrollThumb.qml
T

137 lines
4.4 KiB
QML
Raw Permalink Normal View History

2021-10-30 23:33:48 +02:00
/*
* This file is part of the Flowee project
* Copyright (C) 2021 Tom Zander <tom@flowee.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.11
2021-11-29 18:51:08 +01:00
import QtQuick.Controls 2.11
2021-10-30 23:33:48 +02:00
ScrollBar {
2021-10-30 23:33:48 +02:00
id: root
2021-11-03 11:59:58 +01:00
/// override this if the flickable is not the direct parent.
property var flickable: parent
/// A component will be made visible when the user moves the thumb,
/// allowing the showing of details based on the position
property Component preview: Item {}
background: Item {}
contentItem: Item {}
2021-11-03 11:59:58 +01:00
Item {
parent: root.flickable
anchors.fill: parent
Loader {
anchors.centerIn: parent
sourceComponent: root.preview
opacity: thumbInput.engaged
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InQuad } }
}
2021-11-03 11:59:58 +01:00
}
2021-10-30 23:33:48 +02:00
Rectangle {
id: thumbRect
2021-11-03 11:59:58 +01:00
property bool open: false
property bool moving: root.active || thumbInput.engaged
2021-11-03 11:59:58 +01:00
onMovingChanged: if (moving) open = true
width: 26
height: 42
x: moving || open ? parent.width - width: parent.width + 2
2021-10-30 23:33:48 +02:00
y: {
var pos = root.position
var size = root.size
2021-11-03 11:59:58 +01:00
var viewHeight = root.flickable.height
2021-10-30 23:33:48 +02:00
var newY = viewHeight * pos + viewHeight * size / 2 - height / 2
if (newY < 0)
return 0;
var max = viewHeight - height;
if (newY > max)
return max;
return newY;
}
2021-11-03 11:59:58 +01:00
Column {
id: column
spacing: 2
anchors.centerIn: parent
width: thumbRect.width - 10
Repeater {
model: 3
delegate: Rectangle {
color: root.palette.light
width: column.width
height: 2
radius: 1
}
}
}
color: thumbInput.engaged ? root.palette.highlight : root.palette.dark
2021-10-30 23:33:48 +02:00
2021-11-03 11:59:58 +01:00
Timer {
running: thumbRect.open && !thumbRect.moving
interval: 500
onTriggered: thumbRect.open = false;
2021-10-30 23:33:48 +02:00
}
2021-11-03 11:59:58 +01:00
Behavior on x {
2021-10-30 23:33:48 +02:00
NumberAnimation {
2021-11-03 11:59:58 +01:00
duration: 200
2021-10-30 23:33:48 +02:00
easing.type: Easing.InQuad
}
}
}
MouseArea {
id: thumbInput
2021-11-03 11:59:58 +01:00
// make it easier to grab by having a bigger mouse area than the visial thumb
width: thumbRect.width + 20 + root.width
2021-11-03 11:59:58 +01:00
height: thumbRect.height + 20
2021-10-30 23:33:48 +02:00
anchors.right: parent.right
2021-11-03 11:59:58 +01:00
enabled: thumbRect.moving || thumbRect.open
2021-10-30 23:33:48 +02:00
y: {
var pos = root.position
var size = root.size
2021-11-03 11:59:58 +01:00
var viewHeight = root.flickable.height
2021-10-30 23:33:48 +02:00
return viewHeight * pos + viewHeight * size / 2 - height / 2
}
property int startY: 0
property real startPos: 0
property bool engaged: false // seems that 'Mousearea.pressed' behaves different than I expect, this works better
onPressed: {
2021-11-03 11:59:58 +01:00
startY = root.flickable.mapFromItem(thumbInput, mouse.x, mouse.y).y
startPos = root.position
2021-10-30 23:33:48 +02:00
engaged = true
}
onReleased: engaged = false
preventStealing: true
onPositionChanged: {
// Most of the scroller properties are in the 0.0 - 1.0 range
2021-11-03 11:59:58 +01:00
var absolutePos = root.flickable.mapFromItem(thumbInput, mouse.x, mouse.y);
2021-10-30 23:33:48 +02:00
var diff = startY - absolutePos.y;
2021-11-03 11:59:58 +01:00
var viewHeight = root.flickable.height
2021-10-30 23:33:48 +02:00
var moved = diff / viewHeight;
var newPos = startPos - moved;
if (newPos < 0)
newPos = 0;
var max = 1 - root.size;
2021-10-30 23:33:48 +02:00
if (newPos > max)
newPos = max;
root.position = newPos
}
}
}