background: add visualiser
Also dashboard.visualiserBars -> services.visualiserBars
This commit is contained in:
parent
fd3b98db60
commit
783057ab0d
10 changed files with 181 additions and 13 deletions
14
README.md
14
README.md
|
|
@ -198,7 +198,13 @@ default, you must create it manually.
|
||||||
"desktopClock": {
|
"desktopClock": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"enabled": true
|
"enabled": true,
|
||||||
|
"visualiser": {
|
||||||
|
"enabled": true,
|
||||||
|
"autoHide": true,
|
||||||
|
"rounding": 1,
|
||||||
|
"spacing": 1
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
"dragThreshold": 20,
|
"dragThreshold": 20,
|
||||||
|
|
@ -277,8 +283,7 @@ default, you must create it manually.
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"dragThreshold": 50,
|
"dragThreshold": 50,
|
||||||
"mediaUpdateInterval": 500,
|
"mediaUpdateInterval": 500,
|
||||||
"showOnHover": true,
|
"showOnHover": true
|
||||||
"visualiserBars": 45
|
|
||||||
},
|
},
|
||||||
"launcher": {
|
"launcher": {
|
||||||
"actionPrefix": ">",
|
"actionPrefix": ">",
|
||||||
|
|
@ -324,7 +329,8 @@ default, you must create it manually.
|
||||||
"weatherLocation": "",
|
"weatherLocation": "",
|
||||||
"useFahrenheit": false,
|
"useFahrenheit": false,
|
||||||
"useTwelveHourClock": false,
|
"useTwelveHourClock": false,
|
||||||
"smartScheme": true
|
"smartScheme": true,
|
||||||
|
"visualiserBars": 45
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
"dragThreshold": 30,
|
"dragThreshold": 30,
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,16 @@ import Quickshell.Io
|
||||||
JsonObject {
|
JsonObject {
|
||||||
property bool enabled: true
|
property bool enabled: true
|
||||||
property DesktopClock desktopClock: DesktopClock {}
|
property DesktopClock desktopClock: DesktopClock {}
|
||||||
|
property Visualiser visualiser: Visualiser {}
|
||||||
|
|
||||||
component DesktopClock: JsonObject {
|
component DesktopClock: JsonObject {
|
||||||
property bool enabled: false
|
property bool enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component Visualiser: JsonObject {
|
||||||
|
property bool enabled: true
|
||||||
|
property bool autoHide: true
|
||||||
|
property real rounding: 1
|
||||||
|
property real spacing: 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ JsonObject {
|
||||||
property bool enabled: true
|
property bool enabled: true
|
||||||
property bool showOnHover: true
|
property bool showOnHover: true
|
||||||
property int mediaUpdateInterval: 500
|
property int mediaUpdateInterval: 500
|
||||||
property int visualiserBars: 45
|
|
||||||
property int dragThreshold: 50
|
property int dragThreshold: 50
|
||||||
property Sizes sizes: Sizes {}
|
property Sizes sizes: Sizes {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ JsonObject {
|
||||||
property bool useFahrenheit: [Locale.ImperialUSSystem, Locale.ImperialSystem].includes(Qt.locale().measurementSystem)
|
property bool useFahrenheit: [Locale.ImperialUSSystem, Locale.ImperialSystem].includes(Qt.locale().measurementSystem)
|
||||||
property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a")
|
property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a")
|
||||||
property string gpuType: ""
|
property string gpuType: ""
|
||||||
|
property int visualiserBars: 45
|
||||||
property real audioIncrement: 0.1
|
property real audioIncrement: 0.1
|
||||||
property bool smartScheme: true
|
property bool smartScheme: true
|
||||||
property string defaultPlayer: "Spotify"
|
property string defaultPlayer: "Spotify"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import qs.components
|
||||||
import qs.components.containers
|
import qs.components.containers
|
||||||
|
import qs.services
|
||||||
import qs.config
|
import qs.config
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
|
|
@ -27,7 +31,34 @@ Loader {
|
||||||
anchors.left: true
|
anchors.left: true
|
||||||
anchors.right: true
|
anchors.right: true
|
||||||
|
|
||||||
Wallpaper {}
|
Wallpaper {
|
||||||
|
id: wallpaper
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
readonly property bool shouldBeActive: Config.background.visualiser.enabled && (!Config.background.visualiser.autoHide || Hypr.monitorFor(win.modelData).activeWorkspace.toplevels.values.every(t => t.lastIpcObject.floating)) ? 1 : 0
|
||||||
|
property real offset: shouldBeActive ? 0 : win.modelData.height * 0.2
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: offset
|
||||||
|
anchors.bottomMargin: -offset
|
||||||
|
opacity: shouldBeActive ? 1 : 0
|
||||||
|
active: opacity > 0
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
sourceComponent: Visualiser {
|
||||||
|
screen: win.modelData
|
||||||
|
wallpaper: wallpaper
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on offset {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
|
||||||
120
modules/background/Visualiser.qml
Normal file
120
modules/background/Visualiser.qml
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import qs.components
|
||||||
|
import qs.components.misc
|
||||||
|
import qs.services
|
||||||
|
import qs.config
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
required property Wallpaper wallpaper
|
||||||
|
|
||||||
|
Ref {
|
||||||
|
service: Cava
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: root.wallpaper
|
||||||
|
maskSource: wrapper
|
||||||
|
maskEnabled: true
|
||||||
|
blurEnabled: true
|
||||||
|
blur: 1
|
||||||
|
blurMax: 32
|
||||||
|
autoPaddingEnabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: wrapper
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Config.border.thickness
|
||||||
|
anchors.leftMargin: Visibilities.bars.get(root.screen).exclusiveZone + Appearance.spacing.small * Config.background.visualiser.spacing
|
||||||
|
|
||||||
|
Side {}
|
||||||
|
Side {
|
||||||
|
isRight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on anchors.leftMargin {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Side: Repeater {
|
||||||
|
id: side
|
||||||
|
|
||||||
|
property bool isRight
|
||||||
|
|
||||||
|
model: Config.services.visualiserBars
|
||||||
|
|
||||||
|
ClippingRectangle {
|
||||||
|
id: bar
|
||||||
|
|
||||||
|
required property int modelData
|
||||||
|
property real value: Math.max(1, Math.min(100, Cava.values[side.isRight ? modelData : side.count - modelData - 1])) / 100
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
x: modelData * ((content.width * 0.4) / Config.services.visualiserBars) + (side.isRight ? content.width * 0.6 : 0)
|
||||||
|
implicitWidth: (content.width * 0.4) / Config.services.visualiserBars - Appearance.spacing.small * Config.background.visualiser.spacing
|
||||||
|
|
||||||
|
y: content.height - height
|
||||||
|
implicitHeight: bar.value * content.height * 0.4
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
topLeftRadius: Appearance.rounding.small * Config.background.visualiser.rounding
|
||||||
|
topRightRadius: Appearance.rounding.small * Config.background.visualiser.rounding
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
topLeftRadius: parent.topLeftRadius
|
||||||
|
topRightRadius: parent.topRightRadius
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Vertical
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: Qt.alpha(Colours.palette.m3primary, 0.7)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: Qt.alpha(Colours.palette.m3inversePrimary, 0.7)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
y: parent.height - height
|
||||||
|
implicitHeight: content.height * 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on value {
|
||||||
|
Anim {
|
||||||
|
duration: Appearance.anim.durations.small
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ Item {
|
||||||
id: visualiserBars
|
id: visualiserBars
|
||||||
|
|
||||||
model: Array.from({
|
model: Array.from({
|
||||||
length: Config.dashboard.visualiserBars
|
length: Config.services.visualiserBars
|
||||||
}, (_, i) => i)
|
}, (_, i) => i)
|
||||||
|
|
||||||
ShapePath {
|
ShapePath {
|
||||||
|
|
@ -88,13 +88,13 @@ Item {
|
||||||
required property int modelData
|
required property int modelData
|
||||||
readonly property int value: Math.max(1, Math.min(100, Cava.values[modelData]))
|
readonly property int value: Math.max(1, Math.min(100, Cava.values[modelData]))
|
||||||
|
|
||||||
readonly property real angle: modelData * 2 * Math.PI / Config.dashboard.visualiserBars
|
readonly property real angle: modelData * 2 * Math.PI / Config.services.visualiserBars
|
||||||
readonly property real magnitude: value / 100 * Config.dashboard.sizes.mediaVisualiserSize
|
readonly property real magnitude: value / 100 * Config.dashboard.sizes.mediaVisualiserSize
|
||||||
readonly property real cos: Math.cos(angle)
|
readonly property real cos: Math.cos(angle)
|
||||||
readonly property real sin: Math.sin(angle)
|
readonly property real sin: Math.sin(angle)
|
||||||
|
|
||||||
capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
||||||
strokeWidth: 360 / Config.dashboard.visualiserBars - Appearance.spacing.small / 4
|
strokeWidth: 360 / Config.services.visualiserBars - Appearance.spacing.small / 4
|
||||||
strokeColor: Colours.palette.m3primary
|
strokeColor: Colours.palette.m3primary
|
||||||
|
|
||||||
startX: visualiser.centerX + (visualiser.innerX + strokeWidth / 2) * cos
|
startX: visualiser.centerX + (visualiser.innerX + strokeWidth / 2) * cos
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,8 @@ Variants {
|
||||||
screen: scope.modelData
|
screen: scope.modelData
|
||||||
visibilities: visibilities
|
visibilities: visibilities
|
||||||
popouts: panels.popouts
|
popouts: panels.popouts
|
||||||
|
|
||||||
|
Component.onCompleted: Visibilities.bars.set(scope.modelData, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@ import QtQuick
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property list<int> values: Array(Config.dashboard.visualiserBars)
|
property list<int> values: Array(Config.services.visualiserBars)
|
||||||
property int refCount
|
property int refCount
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Config.dashboard
|
target: Config.services
|
||||||
|
|
||||||
function onVisualiserBarsChanged() {
|
function onVisualiserBarsChanged() {
|
||||||
root.values = Array(Config.dashboard.visualiserBars);
|
root.values = Array(Config.services.visualiserBars);
|
||||||
cavaProc.running = false;
|
cavaProc.running = false;
|
||||||
cavaProc.running = true;
|
cavaProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ Singleton {
|
||||||
id: cavaProc
|
id: cavaProc
|
||||||
|
|
||||||
running: true
|
running: true
|
||||||
command: ["sh", "-c", `printf '[general]\nframerate=60\nbars=${Config.dashboard.visualiserBars}\nsleep_timer=3\n[output]\nchannels=mono\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nascii_max_range=100\n[smoothing]\nnoise_reduction=85\nmonstercat=1\ngravity=120\n[eq]\n1=0.8\n2=0.9\n3=1\n4=1.1\n5=1.2' | cava -p /dev/stdin`]
|
command: ["sh", "-c", `printf '[general]\nframerate=60\nbars=${Config.services.visualiserBars}\nsleep_timer=3\n[output]\nchannels=mono\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nascii_max_range=100\n[smoothing]\nnoise_reduction=85\nmonstercat=1\ngravity=120\n[eq]\n1=0.8\n2=0.9\n3=1\n4=1.1\n5=1.2' | cava -p /dev/stdin`]
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
if (root.refCount)
|
if (root.refCount)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import Quickshell
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
property var screens: new Map()
|
property var screens: new Map()
|
||||||
|
property var bars: new Map()
|
||||||
|
|
||||||
function load(screen: ShellScreen, visibilities: var): void {
|
function load(screen: ShellScreen, visibilities: var): void {
|
||||||
screens.set(Hypr.monitorFor(screen), visibilities);
|
screens.set(Hypr.monitorFor(screen), visibilities);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue