internal: better scroll bar

This commit is contained in:
2 * r + 2 * t 2025-09-19 23:56:17 +10:00
parent 7efc0d54ea
commit ccc398b2a0
6 changed files with 97 additions and 21 deletions

View file

@ -2,17 +2,47 @@ import ".."
import qs.services
import qs.config
import QtQuick
import QtQuick.Controls
import QtQuick.Templates
ScrollBar {
id: root
leftPadding: 0
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: Appearance.padding.small
contentItem: StyledRect {
x: 0
implicitWidth: 6
opacity: root.pressed ? 1 : mouse.containsMouse ? 0.8 : root.policy === ScrollBar.AlwaysOn || (root.active && root.size < 1) ? 0.6 : 0
anchors.left: parent.left
anchors.right: parent.right
opacity: {
if (root.size === 1)
return 0;
if (fullMouse.pressed)
return 1;
if (mouse.containsMouse)
return 0.8;
if (root.policy === ScrollBar.AlwaysOn || root.shouldBeActive)
return 0.6;
return 0;
}
radius: Appearance.rounding.full
color: Colours.palette.m3secondary
@ -30,15 +60,49 @@ ScrollBar {
}
}
CustomMouseArea {
z: -1
anchors.fill: parent
Connections {
target: root.flickable
function onWheel(event: WheelEvent): void {
if (event.angleDelta.y > 0)
root.decrease();
else if (event.angleDelta.y < 0)
root.increase();
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 {}
}
}

View file

@ -11,7 +11,6 @@ import Quickshell
import QtQuick
import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Controls
Item {
id: root
@ -99,7 +98,9 @@ Item {
root.dialog.accepted(currentItem.modelData.path);
}
ScrollBar.vertical: StyledScrollBar {}
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
model: FileSystemModel {
path: {

View file

@ -11,7 +11,6 @@ import Quickshell
import Quickshell.Bluetooth
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ColumnLayout {
id: root
@ -143,8 +142,11 @@ ColumnLayout {
}
StyledListView {
id: view
model: ScriptModel {
id: deviceModel
values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired))
}
@ -153,7 +155,9 @@ ColumnLayout {
clip: true
spacing: Appearance.spacing.small / 2
ScrollBar.vertical: StyledScrollBar {}
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
delegate: StyledRect {
id: device

View file

@ -9,7 +9,6 @@ import qs.services
import qs.config
import Quickshell
import QtQuick
import QtQuick.Controls
StyledListView {
id: root
@ -161,7 +160,9 @@ StyledListView {
}
}
ScrollBar.vertical: StyledScrollBar {}
StyledScrollBar.vertical: StyledScrollBar {
flickable: root
}
add: Transition {
enabled: !root.state

View file

@ -90,6 +90,8 @@ Item {
}
StyledListView {
id: view
anchors.fill: parent
spacing: Appearance.spacing.small
@ -98,7 +100,9 @@ Item {
values: [...new Set(Notifs.list.filter(n => !n.closed).map(n => n.appName))].reverse()
}
StyledScrollBar.vertical: StyledScrollBar {}
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
delegate: MouseArea {
id: notif

View file

@ -66,7 +66,9 @@ ColumnLayout {
implicitHeight: (Appearance.font.size.larger + Appearance.padding.small) * (root.props.recordingListExpanded ? 10 : 3)
clip: true
StyledScrollBar.vertical: StyledScrollBar {}
StyledScrollBar.vertical: StyledScrollBar {
flickable: list
}
delegate: RowLayout {
id: recording