Merge pull request #12 from ferrreo/misc-music-fixes
fix: misc music fixes + add visualizer options
This commit is contained in:
commit
66f11eaa1f
7 changed files with 129 additions and 19 deletions
|
|
@ -9,7 +9,7 @@ import qs.Components
|
||||||
Item {
|
Item {
|
||||||
id: mediaControl
|
id: mediaControl
|
||||||
width: visible ? mediaRow.width : 0
|
width: visible ? mediaRow.width : 0
|
||||||
height: 32
|
height: 36
|
||||||
visible: Settings.showMediaInBar && MusicManager.currentPlayer
|
visible: Settings.showMediaInBar && MusicManager.currentPlayer
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ Scope {
|
||||||
mono_option: monoOption,
|
mono_option: monoOption,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
property var values: Array(count).fill(0) // 0 <= value <= 1
|
property var values: Array(count).fill(0) // 0 <= value <= 1
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
|
|
@ -28,7 +29,7 @@ Scope {
|
||||||
stdinEnabled: true
|
stdinEnabled: true
|
||||||
running: MusicManager.isPlaying
|
running: MusicManager.isPlaying
|
||||||
command: ["cava", "-p", "/dev/stdin"]
|
command: ["cava", "-p", "/dev/stdin"]
|
||||||
onExited: { stdinEnabled = true; index = 0 }
|
onExited: { stdinEnabled = true; index = 0; values = []; }
|
||||||
onStarted: {
|
onStarted: {
|
||||||
const iniParts = []
|
const iniParts = []
|
||||||
for (const k in config) {
|
for (const k in config) {
|
||||||
|
|
@ -55,9 +56,6 @@ Scope {
|
||||||
newValues[i + process.index] = Math.min(data.charCodeAt(i), 128) / 128
|
newValues[i + process.index] = Math.min(data.charCodeAt(i), 128) / 128
|
||||||
}
|
}
|
||||||
process.index += data.length
|
process.index += data.length
|
||||||
if (newValues.length !== values.length) {
|
|
||||||
console.log("length!", values.length, newValues.length)
|
|
||||||
}
|
|
||||||
values = newValues
|
values = newValues
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
import qs.Settings
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -9,9 +10,14 @@ Item {
|
||||||
property color strokeColor: "#fff"
|
property color strokeColor: "#fff"
|
||||||
property int strokeWidth: 0
|
property int strokeWidth: 0
|
||||||
property var values: []
|
property var values: []
|
||||||
|
property int usableOuter: 48
|
||||||
|
|
||||||
width: outerRadius * 2
|
width: usableOuter * 2
|
||||||
height: outerRadius * 2
|
height: usableOuter * 2
|
||||||
|
|
||||||
|
onOuterRadiusChanged: () => {
|
||||||
|
usableOuter = Settings.visualizerType === "fire" ? outerRadius * 0.85 : outerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.values.length
|
model: root.values.length
|
||||||
|
|
@ -19,23 +25,33 @@ Item {
|
||||||
property real value: root.values[index]
|
property real value: root.values[index]
|
||||||
property real angle: (index / root.values.length) * 360
|
property real angle: (index / root.values.length) * 360
|
||||||
width: Math.max(2, (root.innerRadius * 2 * Math.PI) / root.values.length - 4)
|
width: Math.max(2, (root.innerRadius * 2 * Math.PI) / root.values.length - 4)
|
||||||
height: value * (root.outerRadius - root.innerRadius)
|
height: Settings.visualizerType === "diamond" ? value * 2 * (usableOuter - root.innerRadius) : value * (usableOuter - root.innerRadius)
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
color: root.fillColor
|
color: root.fillColor
|
||||||
border.color: root.strokeColor
|
border.color: root.strokeColor
|
||||||
border.width: root.strokeWidth
|
border.width: root.strokeWidth
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
|
|
||||||
x: root.width / 2 + (root.innerRadius) * Math.cos(Math.PI/2 + 2 * Math.PI * index / root.values.length) - width / 2
|
x: Settings.visualizerType === "radial" ? root.width / 2 - width / 2 : root.width / 2 + root.innerRadius * Math.cos(Math.PI / 2 + 2 * Math.PI * index / root.values.length) - width / 2
|
||||||
y: root.height / 2 - (root.innerRadius) * Math.sin(Math.PI/2 + 2 * Math.PI * index / root.values.length) - height
|
|
||||||
|
|
||||||
transform: Rotation {
|
y: Settings.visualizerType === "radial" ? root.height / 2 - height : Settings.visualizerType === "diamond" ? root.height / 2 - root.innerRadius * Math.sin(Math.PI / 2 + 2 * Math.PI * index / root.values.length) - height / 2 : root.height / 2 - root.innerRadius * Math.sin(Math.PI / 2 + 2 * Math.PI * index / root.values.length) - height
|
||||||
|
transform: [
|
||||||
|
Rotation {
|
||||||
origin.x: width / 2
|
origin.x: width / 2
|
||||||
origin.y: height
|
origin.y: Settings.visualizerType === "diamond" ? height / 2 : height
|
||||||
angle: -angle
|
angle: Settings.visualizerType === "radial" ? (index / root.values.length) * 360 : Settings.visualizerType === "fire" ? 0 : (index / root.values.length) * 360 - 90
|
||||||
|
},
|
||||||
|
Translate {
|
||||||
|
x: Settings.visualizerType === "radial" ? root.innerRadius * Math.cos(2 * Math.PI * index / root.values.length) : 0
|
||||||
|
y: Settings.visualizerType === "radial" ? root.innerRadius * Math.sin(2 * Math.PI * index / root.values.length) : 0
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
Behavior on height { SmoothedAnimation { duration: 120 } }
|
Behavior on height {
|
||||||
|
SmoothedAnimation {
|
||||||
|
duration: 120
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,6 +29,7 @@ QtObject {
|
||||||
property int transitionFps: 60
|
property int transitionFps: 60
|
||||||
property string transitionType: "random"
|
property string transitionType: "random"
|
||||||
property real transitionDuration: 1.1
|
property real transitionDuration: 1.1
|
||||||
|
property string visualizerType: "radial" // Options: "fire", "diamond", "radial"
|
||||||
|
|
||||||
// Settings persistence
|
// Settings persistence
|
||||||
property var settings: Settings {
|
property var settings: Settings {
|
||||||
|
|
@ -60,6 +61,7 @@ QtObject {
|
||||||
transitionFps = settings.value("transitionFps", transitionFps)
|
transitionFps = settings.value("transitionFps", transitionFps)
|
||||||
transitionType = settings.value("transitionType", transitionType)
|
transitionType = settings.value("transitionType", transitionType)
|
||||||
transitionDuration = settings.value("transitionDuration", transitionDuration)
|
transitionDuration = settings.value("transitionDuration", transitionDuration)
|
||||||
|
visualizerType = settings.value("visualizerType", visualizerType)
|
||||||
|
|
||||||
WallpaperManager.setCurrentWallpaper(currentWallpaper, true);
|
WallpaperManager.setCurrentWallpaper(currentWallpaper, true);
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +84,7 @@ QtObject {
|
||||||
settings.setValue("transitionFps", transitionFps)
|
settings.setValue("transitionFps", transitionFps)
|
||||||
settings.setValue("transitionType", transitionType)
|
settings.setValue("transitionType", transitionType)
|
||||||
settings.setValue("transitionDuration", transitionDuration)
|
settings.setValue("transitionDuration", transitionDuration)
|
||||||
|
settings.setValue("visualizerType", visualizerType)
|
||||||
settings.sync()
|
settings.sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import qs.Settings
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: profileSettingsCard
|
id: profileSettingsCard
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 300
|
Layout.preferredHeight: 340
|
||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
radius: 18
|
radius: 18
|
||||||
border.color: "transparent"
|
border.color: "transparent"
|
||||||
|
|
@ -19,6 +19,8 @@ Rectangle {
|
||||||
signal showSystemInfoChanged(bool showSystemInfoInBar)
|
signal showSystemInfoChanged(bool showSystemInfoInBar)
|
||||||
property bool showMediaInBar: false
|
property bool showMediaInBar: false
|
||||||
signal showMediaChanged(bool showMediaInBar)
|
signal showMediaChanged(bool showMediaInBar)
|
||||||
|
property string visualizerType: Settings.visualizerType
|
||||||
|
signal visualizerTypeUpdated(string type)
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -284,6 +286,88 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Visualizer Type Selection
|
||||||
|
RowLayout {
|
||||||
|
spacing: 8
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Visualizer Type"
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.bold: true
|
||||||
|
color: Theme.textPrimary
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown for visualizer type
|
||||||
|
Rectangle {
|
||||||
|
width: 120
|
||||||
|
height: 36
|
||||||
|
radius: 8
|
||||||
|
color: Theme.surfaceVariant
|
||||||
|
border.color: Theme.outline
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: visualizerTypeText
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: visualizerType === "fire" ? "Fire" :
|
||||||
|
visualizerType === "diamond" ? "Diamond" :
|
||||||
|
visualizerType === "radial" ? "Radial" : "Radial"
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Theme.textPrimary
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "arrow_drop_down"
|
||||||
|
font.family: "Material Symbols Outlined"
|
||||||
|
font.pixelSize: 20
|
||||||
|
color: Theme.textPrimary
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
visualizerTypeMenu.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: visualizerTypeMenu
|
||||||
|
width: 120
|
||||||
|
y: parent.height
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Fire"
|
||||||
|
onTriggered: {
|
||||||
|
visualizerTypeUpdated("fire")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: "Diamond"
|
||||||
|
onTriggered: {
|
||||||
|
visualizerTypeUpdated("diamond")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: "Radial"
|
||||||
|
onTriggered: {
|
||||||
|
visualizerTypeUpdated("radial")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Video Path Input Row
|
// Video Path Input Row
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ PanelWindow {
|
||||||
property real tempTransitionDuration: Settings.transitionDuration
|
property real tempTransitionDuration: Settings.transitionDuration
|
||||||
property bool tempShowSystemInfoInBar: Settings.showSystemInfoInBar
|
property bool tempShowSystemInfoInBar: Settings.showSystemInfoInBar
|
||||||
property bool tempShowMediaInBar: Settings.showMediaInBar
|
property bool tempShowMediaInBar: Settings.showMediaInBar
|
||||||
|
property string tempVisualizerType: Settings.visualizerType
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -151,6 +152,10 @@ PanelWindow {
|
||||||
onShowMediaChanged: function (showMediaInBar) {
|
onShowMediaChanged: function (showMediaInBar) {
|
||||||
tempShowMediaInBar = showMediaInBar;
|
tempShowMediaInBar = showMediaInBar;
|
||||||
}
|
}
|
||||||
|
visualizerType: tempVisualizerType
|
||||||
|
onVisualizerTypeUpdated: function (type) {
|
||||||
|
tempVisualizerType = type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CollapsibleCategory {
|
CollapsibleCategory {
|
||||||
|
|
@ -236,6 +241,7 @@ PanelWindow {
|
||||||
Settings.transitionDuration = tempTransitionDuration;
|
Settings.transitionDuration = tempTransitionDuration;
|
||||||
Settings.showSystemInfoInBar = tempShowSystemInfoInBar;
|
Settings.showSystemInfoInBar = tempShowSystemInfoInBar;
|
||||||
Settings.showMediaInBar = tempShowMediaInBar;
|
Settings.showMediaInBar = tempShowMediaInBar;
|
||||||
|
Settings.visualizerType = tempVisualizerType;
|
||||||
Settings.saveSettings();
|
Settings.saveSettings();
|
||||||
if (typeof weather !== 'undefined' && weather) {
|
if (typeof weather !== 'undefined' && weather) {
|
||||||
weather.fetchCityWeather();
|
weather.fetchCityWeather();
|
||||||
|
|
@ -266,6 +272,9 @@ PanelWindow {
|
||||||
tempTransitionFps = Settings.transitionFps;
|
tempTransitionFps = Settings.transitionFps;
|
||||||
tempTransitionType = Settings.transitionType;
|
tempTransitionType = Settings.transitionType;
|
||||||
tempTransitionDuration = Settings.transitionDuration;
|
tempTransitionDuration = Settings.transitionDuration;
|
||||||
|
tempShowSystemInfoInBar = Settings.showSystemInfoInBar;
|
||||||
|
tempShowMediaInBar = Settings.showMediaInBar;
|
||||||
|
tempVisualizerType = Settings.visualizerType;
|
||||||
|
|
||||||
visible = true;
|
visible = true;
|
||||||
// Force focus on the text input after a short delay
|
// Force focus on the text input after a short delay
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 18
|
anchors.margins: 18
|
||||||
spacing: 12
|
spacing: 12
|
||||||
visible: currentPlayer
|
visible: !!MusicManager.currentPlayer
|
||||||
|
|
||||||
// Album art and spectrum
|
// Album art and spectrum
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue