Files
illogical-impulse/.config/quickshell/modules/common/widgets/StyledProgressBar.qml
T
2025-06-17 23:20:06 +02:00

105 lines
3.6 KiB
QML

import "root:/services"
import "root:/modules/common"
import "root:/modules/common/widgets"
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Widgets
import Qt5Compat.GraphicalEffects
/**
* Material 3 progress bar. See https://m3.material.io/components/progress-indicators/overview
*/
ProgressBar {
id: root
property real valueBarWidth: 120
property real valueBarHeight: 4
property real valueBarGap: 4
property color highlightColor: Appearance?.colors.colPrimary ?? "#685496"
property color trackColor: Appearance?.m3colors.m3secondaryContainer ?? "#F1D3F9"
property bool sperm: false // If true, the progress bar will have a wavy fill effect
property bool animateSperm: true
property real spermAmplitudeMultiplier: sperm ? 0.5 : 0
property real spermFrequency: 6
property real spermFps: 60
Behavior on spermAmplitudeMultiplier {
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
}
Behavior on value {
animation: Appearance?.animation.elementMoveEnter.numberAnimation.createObject(this)
}
background: Rectangle {
anchors.fill: parent
color: "transparent"
radius: Appearance?.rounding.full ?? 9999
implicitHeight: valueBarHeight
implicitWidth: valueBarWidth
}
contentItem: Item {
anchors.fill: parent
Canvas {
id: wavyFill
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
height: parent.height * 6
onPaint: {
var ctx = getContext("2d");
ctx.clearRect(0, 0, width, height);
var progress = root.visualPosition;
var fillWidth = progress * width;
var amplitude = parent.height * root.spermAmplitudeMultiplier;
var frequency = root.spermFrequency;
var phase = Date.now() / 400.0;
var centerY = height / 2;
ctx.strokeStyle = root.highlightColor;
ctx.lineWidth = parent.height;
ctx.lineCap = "round";
ctx.beginPath();
for (var x = ctx.lineWidth / 2; x <= fillWidth; x += 1) {
var waveY = centerY + amplitude * Math.sin(frequency * 2 * Math.PI * x / width + phase);
if (x === 0)
ctx.moveTo(x, waveY);
else
ctx.lineTo(x, waveY);
}
ctx.stroke();
}
Connections {
target: root
function onValueChanged() { wavyFill.requestPaint(); }
function onHighlightColorChanged() { wavyFill.requestPaint(); }
}
Timer {
interval: 1000 / root.spermFps
running: root.animateSperm
repeat: root.sperm
onTriggered: wavyFill.requestPaint()
}
}
Rectangle { // Right remaining part fill
anchors.right: parent.right
width: (1 - root.visualPosition) * parent.width - valueBarGap
height: parent.height
radius: Appearance?.rounding.full ?? 9999
color: root.trackColor
}
Rectangle { // Stop point
anchors.right: parent.right
width: valueBarGap
height: valueBarGap
radius: Appearance?.rounding.full ?? 9999
color: root.highlightColor
}
}
}