fix: proper non-wavy slider

Also not wavy by default
This commit is contained in:
2 * r + 2 * t 2026-05-04 19:44:24 +10:00
parent 69185acd08
commit 5f2e772250
2 changed files with 64 additions and 39 deletions

View file

@ -1,3 +1,5 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import Caelestia import Caelestia
@ -9,18 +11,21 @@ import qs.services
Slider { Slider {
id: root id: root
property bool wavy: true property bool wavy
property bool animateWave property bool animateWave
property alias waveFrequency: wave.frequency property real waveFrequency: 6
property alias waveDuration: waveAnim.duration property int waveDuration: 1000
property color fgColour: enabled ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3onSurface, 0.38) property color fgColour: enabled ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3onSurface, 0.38)
property color bgColour: enabled ? Colours.palette.m3secondaryContainer : Qt.alpha(Colours.palette.m3onSurface, 0.1) property color bgColour: enabled ? Colours.palette.m3secondaryContainer : Qt.alpha(Colours.palette.m3onSurface, 0.1)
property real pos: visualPosition property real pos: visualPosition
property real filledWidth
signal interaction(v: real) signal interaction(v: real)
Component.onCompleted: filledWidth = Qt.binding(() => (width - handle.implicitWidth - handle.anchors.leftMargin) * pos)
implicitWidth: 200 implicitWidth: 200
implicitHeight: 12 implicitHeight: 12
@ -35,10 +40,10 @@ Slider {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Tokens.spacing.extraSmall anchors.leftMargin: Tokens.spacing.extraSmall
implicitHeight: Math.min(width, parent.height) implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1))
opacity: implicitHeight / parent.height opacity: Math.min(width, 12) / 12
radius: Tokens.rounding.full radius: Tokens.rounding.medium
topLeftRadius: Tokens.rounding.extraSmall / 2 topLeftRadius: Tokens.rounding.extraSmall / 2
bottomLeftRadius: Tokens.rounding.extraSmall / 2 bottomLeftRadius: Tokens.rounding.extraSmall / 2
color: root.bgColour color: root.bgColour
@ -47,7 +52,7 @@ Slider {
StyledRect { StyledRect {
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: (parent.height - implicitHeight) / 2 * remaining.opacity anchors.rightMargin: 4 * remaining.opacity
implicitWidth: implicitHeight implicitWidth: implicitHeight
implicitHeight: 4 * remaining.opacity implicitHeight: 4 * remaining.opacity
@ -60,12 +65,16 @@ Slider {
StyledRect { StyledRect {
id: handle id: handle
anchors.left: wave.right anchors.left: filled.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Tokens.spacing.extraSmall anchors.leftMargin: Tokens.spacing.extraSmall
implicitWidth: 4 implicitWidth: 4
implicitHeight: parent.height * (mouse.pressed ? 4 : 3) implicitHeight: {
const mult = parent.height <= 12 ? 3 : 1.2;
const pressMult = parent.height <= 12 ? 4 : 1.5;
return parent.height * (mouse.pressed ? pressMult : mult);
}
radius: Tokens.rounding.full radius: Tokens.rounding.full
color: root.fgColour color: root.fgColour
@ -77,47 +86,56 @@ Slider {
} }
} }
WavyLine { Loader {
id: wave id: filled
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth asynchronous: true
lineWidth: parent.height * (root.wavy ? 0.7 : 1) sourceComponent: root.wavy ? waveComp : lineComp
amplitudeMultiplier: root.wavy ? 0.5 : 0 }
Component {
id: lineComp
StyledRect {
implicitWidth: root.filledWidth
implicitHeight: root.height
radius: Tokens.rounding.medium
topRightRadius: Tokens.rounding.extraSmall / 2
bottomRightRadius: Tokens.rounding.extraSmall / 2
color: root.fgColour
}
}
Component {
id: waveComp
WavyLine {
lineWidth: root.height * 0.7
frequency: root.waveFrequency
startX: x startX: x
fullLength: parent.width - handle.implicitWidth - handle.anchors.leftMargin fullLength: root.width - handle.implicitWidth - handle.anchors.leftMargin
color: root.fgColour color: root.fgColour
Component.onCompleted: implicitWidth = Qt.binding(() => fullLength * root.pos) implicitWidth: root.filledWidth
implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth
Anim on waveProgress { Anim on waveProgress {
id: waveAnim
running: true running: true
paused: !root.animateWave paused: !root.animateWave
from: 0 from: 0
to: 1 to: 1
duration: 1000 duration: root.waveDuration
easing.type: Easing.Linear easing.type: Easing.Linear
loops: Animation.Infinite loops: Animation.Infinite
} }
Behavior on amplitudeMultiplier {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on color { Behavior on color {
CAnim {} CAnim {}
} }
Behavior on implicitWidth {
id: widthBehavior
Anim {}
} }
} }
} }
@ -157,4 +175,10 @@ Slider {
dragMovement = 0; dragMovement = 0;
} }
} }
Behavior on filledWidth {
id: widthBehavior
Anim {}
}
} }

View file

@ -83,6 +83,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
value: Players.active ? Players.active.position / (Players.active.length || 1) : 0 value: Players.active ? Players.active.position / (Players.active.length || 1) : 0
enabled: Players.active?.canSeek ?? false enabled: Players.active?.canSeek ?? false
wavy: true
animateWave: Players.active?.isPlaying ?? false animateWave: Players.active?.isPlaying ?? false
waveFrequency: 5 waveFrequency: 5
waveDuration: 2000 waveDuration: 2000