diff --git a/Config/Config.qml b/Config/Config.qml index a12cb8f..d5c1abe 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -188,7 +188,7 @@ Singleton { resourceProgessThickness: dashboard.sizes.resourceProgessThickness, weatherWidth: dashboard.sizes.weatherWidth, mediaCoverArtSize: dashboard.sizes.mediaCoverArtSize, - mediaVisualiserSize: dashboard.sizes.mediaVisualiserSize, + mediaVisualizerSize: dashboard.sizes.mediaVisualizerSize, resourceSize: dashboard.sizes.resourceSize } }; diff --git a/Config/DashboardConfig.qml b/Config/DashboardConfig.qml index 0b6a610..e0286bb 100644 --- a/Config/DashboardConfig.qml +++ b/Config/DashboardConfig.qml @@ -25,7 +25,7 @@ JsonObject { readonly property int mediaCoverArtSize: 150 readonly property int mediaProgressSweep: 180 readonly property int mediaProgressThickness: 8 - readonly property int mediaVisualiserSize: 80 + readonly property int mediaVisualizerSize: 200 readonly property int mediaWidth: 200 readonly property int resourceProgessThickness: 10 readonly property int resourceSize: 200 diff --git a/Modules/Dashboard/Dash/Media.qml b/Modules/Dashboard/Dash/Media.qml index bc12293..3dba6e8 100644 --- a/Modules/Dashboard/Dash/Media.qml +++ b/Modules/Dashboard/Dash/Media.qml @@ -4,6 +4,7 @@ import Quickshell import QtQuick import QtQuick.Layouts import QtQuick.Shapes +import QtQuick.Effects import ZShell.Services import qs.Daemons import qs.Components @@ -45,49 +46,85 @@ Item { Shape { id: visualizer - readonly property real barW: Math.max(0, (width - gap * (bars - 1)) / bars) readonly property int bars: Config.services.visualizerBars - property color color: DynamicColors.palette.m3primary - readonly property real gap: Appearance.spacing.small + property color color: DynamicColors.palette.m3tertiary + property color fillColor: Qt.alpha(color, 0.25) anchors.fill: layout + anchors.leftMargin: -(shape.strokeWidth / 2) + layer.enabled: true asynchronous: true - data: visualizerBars.instances preferredRendererType: Shape.CurveRenderer - } - - Variants { - id: visualizerBars - - model: Array.from({ - length: Config.services.visualizerBars - }, (_, i) => i) ShapePath { - id: visualizerBar - - readonly property real magnitude: value * Config.dashboard.sizes.mediaVisualiserSize - required property int modelData - readonly property real value: Math.max(1e-3, Audio.cava.values[modelData]) - - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap - startX: (visualizer.barW / 2) + modelData * (visualizer.barW + visualizer.gap) - startY: layout.y + layout.height + id: shape strokeColor: visualizer.color - strokeWidth: visualizer.barW + fillColor: visualizer.fillColor + strokeWidth: 2 - Behavior on strokeColor { - CAnim { + PathSvg { + path: shape.curvePath + } + + property string curvePath: { + const values = Audio.cava.values; + const n = values.length; + + if (n < 2) + return ""; + + const h = layout.height + shape.strokeWidth / 2; + const w = layout.width + shape.strokeWidth; + + function x(i) { + return i * w / (n - 1); } - } - PathLine { - relativeX: 0 - relativeY: -visualizerBar.magnitude + function y(i) { + return h - values[i] * Config.dashboard.sizes.mediaVisualizerSize; + } + + let d = `M 0 ${h} `; + d += `L ${x(0)} ${y(0)} `; + + for (let i = 0; i < n - 1; ++i) { + const x0 = x(i); + const y0 = y(i); + + const x1 = x(i + 1); + const y1 = y(i + 1); + + const prev = Math.max(0, i - 1); + const next = Math.min(n - 1, i + 2); + + const c1x = x0 + (x1 - x(prev)) / 6; + const c1y = y0 + (y1 - y(prev)) / 6; + + const c2x = x1 - (x(next) - x0) / 6; + const c2y = y1 - (y(next) - y0) / 6; + + d += `C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x1} ${y1} `; + } + + d += `L ${w} ${h} `; + d += `L 0 ${h} Z`; + + return d; } } } + CustomRect { + anchors.fill: visualizer + + color: Qt.alpha(DynamicColors.palette.m3shadow, 0.2) + layer.enabled: true + layer.effect: MultiEffect { + maskEnabled: true + maskSource: visualizer + } + } + Shape { preferredRendererType: Shape.CurveRenderer diff --git a/Modules/Settings/Categories/Services.qml b/Modules/Settings/Categories/Services.qml index c1ef0c4..ef7bb7a 100644 --- a/Modules/Settings/Categories/Services.qml +++ b/Modules/Settings/Categories/Services.qml @@ -127,7 +127,7 @@ SettingsPage { SettingSpinBox { min: 1 - name: "Visualizer bars" + name: "Visualizer resolution" object: Config.services setting: "visualizerBars" step: 1 diff --git a/Plugins/ZShell/Services/cavaprovider.cpp b/Plugins/ZShell/Services/cavaprovider.cpp index 8715f39..ec64db2 100644 --- a/Plugins/ZShell/Services/cavaprovider.cpp +++ b/Plugins/ZShell/Services/cavaprovider.cpp @@ -36,7 +36,7 @@ void CavaProcessor::process() { QVector values(m_bars); for(int i = 0; i < m_bars; ++i) { - values[i] = std::clamp(m_out[i], 0.0, 1.0); + values[i] = m_out[i]; } // Left to right pass