From 5e59b5e2a48145e864d8188d87f0e9631f61478f Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Mon, 4 May 2026 00:14:33 +1000 Subject: [PATCH] feat: improve slider --- components/controls/StyledSlider.qml | 159 ++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 28 deletions(-) diff --git a/components/controls/StyledSlider.qml b/components/controls/StyledSlider.qml index f169691b..84cb4818 100644 --- a/components/controls/StyledSlider.qml +++ b/components/controls/StyledSlider.qml @@ -1,5 +1,7 @@ import QtQuick import QtQuick.Templates +import Caelestia +import Caelestia.Components import Caelestia.Config import qs.components import qs.services @@ -7,51 +9,152 @@ import qs.services Slider { id: root - background: Item { + property bool wavy: true + property bool animateWave + property alias waveFrequency: wave.frequency + property alias waveDuration: waveAnim.duration + + 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 real pos: visualPosition + + signal interaction(v: real) + + implicitWidth: 200 + implicitHeight: 8 + + contentItem: Item { + anchors.fill: parent + StyledRect { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.topMargin: root.implicitHeight / 3 - anchors.bottomMargin: root.implicitHeight / 3 + id: remaining - implicitWidth: root.handle.x - root.implicitHeight / 6 + anchors.left: handle.right + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Tokens.spacing.extraSmall + + implicitHeight: Math.min(width, parent.height) + opacity: implicitHeight / parent.height - color: Colours.palette.m3primary radius: Tokens.rounding.full - topRightRadius: root.implicitHeight / 15 - bottomRightRadius: root.implicitHeight / 15 + topLeftRadius: Tokens.rounding.extraSmall / 2 + bottomLeftRadius: Tokens.rounding.extraSmall / 2 + color: root.bgColour } StyledRect { - anchors.top: parent.top - anchors.bottom: parent.bottom anchors.right: parent.right - anchors.topMargin: root.implicitHeight / 3 - anchors.bottomMargin: root.implicitHeight / 3 + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: (parent.height - implicitHeight) / 2 * remaining.opacity - implicitWidth: parent.width - root.handle.x - root.handle.implicitWidth - root.implicitHeight / 6 + implicitWidth: implicitHeight + implicitHeight: 4 * remaining.opacity + opacity: remaining.opacity - color: Colours.palette.m3surfaceContainerHighest radius: Tokens.rounding.full - topLeftRadius: root.implicitHeight / 15 - bottomLeftRadius: root.implicitHeight / 15 + color: root.fgColour + } + + StyledRect { + id: handle + + anchors.left: wave.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Tokens.spacing.extraSmall + + implicitWidth: parent.height * 0.75 + implicitHeight: parent.height * (mouse.pressed ? 5 : 4) + + radius: Tokens.rounding.full + color: root.fgColour + + Behavior on implicitHeight { + Anim { + type: Anim.FastSpatial + } + } + } + + WavyLine { + id: wave + + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth + + lineWidth: parent.height - 1 + amplitudeMultiplier: root.wavy ? 0.5 : 0 + startX: x + fullLength: parent.width - handle.implicitWidth - handle.anchors.leftMargin + color: root.fgColour + + Component.onCompleted: implicitWidth = Qt.binding(() => fullLength * root.pos) + + Anim on waveProgress { + id: waveAnim + + running: true + paused: !root.animateWave + from: 0 + to: 1 + duration: 1000 + easing.type: Easing.Linear + loops: Animation.Infinite + } + + Behavior on amplitudeMultiplier { + Anim { + type: Anim.DefaultEffects + } + } + + Behavior on color { + CAnim {} + } + + Behavior on implicitWidth { + id: widthBehavior + + Anim {} + } } } - handle: StyledRect { - x: root.visualPosition * root.availableWidth - implicitWidth / 2 + Binding { + id: posBinding - implicitWidth: root.implicitHeight / 4.5 - implicitHeight: root.implicitHeight + target: root + property: "pos" + value: CUtils.clamp(mouse.pressStartPos + mouse.dragMovement, 0, 1) + when: mouse.pressed + } - color: Colours.palette.m3primary - radius: Tokens.rounding.full + MouseArea { + id: mouse - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.NoButton - cursorShape: Qt.PointingHandCursor + property real pressStartX + property real pressStartPos + property real dragMovement + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + preventStealing: true + implicitHeight: handle.implicitHeight + + onPressed: e => { + widthBehavior.enabled = false; + pressStartX = e.x; + pressStartPos = root.visualPosition; + } + onPositionChanged: e => dragMovement = (e.x - pressStartX) / width + onReleased: e => { + root.interaction(posBinding.value); + widthBehavior.enabled = true; + dragMovement = 0; } } }