Settings window #20

Merged
Zacharias-Brohn merged 83 commits from settingsWindow into main 2026-03-06 23:27:24 +01:00
17 changed files with 84 additions and 56 deletions
Showing only changes of commit 5f875915f4 - Show all commits
-4
View File
@@ -51,10 +51,6 @@ Slider {
implicitWidth: root.implicitWidth - root.handle.x - root.handle.implicitWidth - root.implicitHeight implicitWidth: root.implicitWidth - root.handle.x - root.handle.implicitWidth - root.implicitHeight
radius: 1000 radius: 1000
topLeftRadius: root.implicitHeight / 15 topLeftRadius: root.implicitHeight / 15
Component.onCompleted: {
console.log(root.handle.x, implicitWidth);
}
} }
} }
handle: CustomRect { handle: CustomRect {
+3 -5
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Effects import qs.Config
Item { Item {
id: root id: root
@@ -12,15 +12,13 @@ Item {
property int gap: 40 property int gap: 40
property alias horizontalAlignment: elideText.horizontalAlignment property alias horizontalAlignment: elideText.horizontalAlignment
property bool leftFadeEnabled: false property bool leftFadeEnabled: false
property real leftFadeStrength: overflowing && leftFadeEnabled property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
? fadeStrengthMoving : fadeStrengthIdle
property int leftFadeWidth: 28 property int leftFadeWidth: 28
property bool marqueeEnabled: true property bool marqueeEnabled: true
readonly property bool overflowing: metrics.width > root.width readonly property bool overflowing: metrics.width > root.width
property int pauseMs: 1200 property int pauseMs: 1200
property real pixelsPerSecond: 40 property real pixelsPerSecond: 40
property real rightFadeStrength: overflowing ? fadeStrengthMoving : property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
fadeStrengthIdle
property int rightFadeWidth: 28 property int rightFadeWidth: 28
property bool sliding: false property bool sliding: false
property alias text: elideText.text property alias text: elideText.text
+8 -13
View File
@@ -242,7 +242,8 @@ Singleton {
brightnessIncrement: services.brightnessIncrement, brightnessIncrement: services.brightnessIncrement,
maxVolume: services.maxVolume, maxVolume: services.maxVolume,
defaultPlayer: services.defaultPlayer, defaultPlayer: services.defaultPlayer,
playerAliases: services.playerAliases playerAliases: services.playerAliases,
visualizerBars: services.visualizerBars
}; };
} }
@@ -307,8 +308,7 @@ Singleton {
fileView.setText(JSON.stringify(config, null, 4)); fileView.setText(JSON.stringify(config, null, 4));
} catch (e) { } catch (e) {
Toaster.toast(qsTr("Failed to serialize config"), e.message, Toaster.toast(qsTr("Failed to serialize config"), e.message, "settings_alert", Toast.Error);
"settings_alert", Toast.Error);
} }
} }
} }
@@ -339,8 +339,7 @@ Singleton {
} }
onLoadFailed: err => { onLoadFailed: err => {
if (err !== FileViewError.FileNotFound) if (err !== FileViewError.FileNotFound)
Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), "settings_alert", Toast.Warning);
"settings_alert", Toast.Warning);
} }
onLoaded: { onLoaded: {
ModeScheduler.checkStartup(); ModeScheduler.checkStartup();
@@ -349,19 +348,15 @@ Singleton {
const elapsed = timer.elapsedMs(); const elapsed = timer.elapsedMs();
if (adapter.utilities.toasts.configLoaded && !root.recentlySaved) { if (adapter.utilities.toasts.configLoaded && !root.recentlySaved) {
Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg( Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg(elapsed), "rule_settings");
elapsed), "rule_settings");
} else if (adapter.utilities.toasts.configLoaded && root.recentlySaved) { } else if (adapter.utilities.toasts.configLoaded && root.recentlySaved) {
Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg( Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg(elapsed), "settings_alert");
elapsed), "settings_alert");
} }
} catch (e) { } catch (e) {
Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", Toast.Error);
Toast.Error);
} }
} }
onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), FileViewError.toString(err), "settings_alert", Toast.Error)
FileViewError.toString(err), "settings_alert", Toast.Error)
JsonAdapter { JsonAdapter {
id: adapter id: adapter
+1
View File
@@ -15,5 +15,6 @@ JsonObject {
] ]
property bool useFahrenheit: false property bool useFahrenheit: false
property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a") property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a")
property int visualizerBars: 30
property string weatherLocation: "" property string weatherLocation: ""
} }
+8 -1
View File
@@ -1,15 +1,16 @@
pragma Singleton pragma Singleton
import qs.Config
import ZShell.Services import ZShell.Services
import ZShell import ZShell
import Quickshell import Quickshell
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import QtQuick import QtQuick
import qs.Config
Singleton { Singleton {
id: root id: root
readonly property alias cava: cava
readonly property bool muted: !!sink?.audio?.muted readonly property bool muted: !!sink?.audio?.muted
readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => { readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => {
if (!node.isStream) { if (!node.isStream) {
@@ -131,6 +132,12 @@ Singleton {
previousSourceName = newSourceName; previousSourceName = newSourceName;
} }
CavaProvider {
id: cava
bars: Config.services.visualizerBars
}
PwObjectTracker { PwObjectTracker {
objects: [...root.sinks, ...root.sources, ...root.streams] objects: [...root.sinks, ...root.sources, ...root.streams]
} }
-3
View File
@@ -23,9 +23,6 @@ Shape {
anchors.topMargin: bar.implicitHeight anchors.topMargin: bar.implicitHeight
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
Component.onCompleted: console.log(root.bar.implicitHeight,
root.bar.anchors.topMargin)
Osd.Background { Osd.Background {
startX: root.width - root.panels.sidebar.width startX: root.width - root.panels.sidebar.width
startY: (root.height - wrapper.height) / 2 - rounding startY: (root.height - wrapper.height) / 2 - rounding
-1
View File
@@ -240,7 +240,6 @@ CustomMouseArea {
if (root.visibilities.osd) { if (root.visibilities.osd) {
// OSD became visible, immediately check if this should be shortcut mode // OSD became visible, immediately check if this should be shortcut mode
const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY);
console.log(inOsdArea);
if (!inOsdArea) { if (!inOsdArea) {
root.osdShortcutActive = true; root.osdShortcutActive = true;
} }
-2
View File
@@ -10,8 +10,6 @@ Singleton {
let activeClass = Hypr.activeToplevel.lastIpcObject.class.toString(); let activeClass = Hypr.activeToplevel.lastIpcObject.class.toString();
let regex = new RegExp(activeClass, "i"); let regex = new RegExp(activeClass, "i");
console.log("ActiveWindow", activeWindow, "ActiveClass", activeClass, "Regex", regex);
const evalTitle = activeWindow.match(regex); const evalTitle = activeWindow.match(regex);
callback(evalTitle); callback(evalTitle);
} }
+1
View File
@@ -213,6 +213,7 @@ Item {
radius: 1000 radius: 1000
MaterialIcon { MaterialIcon {
anchors.alignWhenCentered: false
anchors.centerIn: parent anchors.centerIn: parent
color: DynamicColors.palette.m3onPrimary color: DynamicColors.palette.m3onPrimary
font.pointSize: 22 font.pointSize: 22
-9
View File
@@ -71,7 +71,6 @@ GridLayout {
Layout.preferredWidth: 40 Layout.preferredWidth: 40
color: { color: {
if (modelData.isToday) { if (modelData.isToday) {
console.log(width);
return DynamicColors.palette.m3primaryContainer; return DynamicColors.palette.m3primaryContainer;
} }
return "transparent"; return "transparent";
@@ -108,14 +107,6 @@ GridLayout {
} }
} }
} }
StateLayer {
color: DynamicColors.palette.m3onSurface
onClicked: {
console.log(`Selected date: ${parent.modelData.day}/${parent.modelData.month + 1}/${parent.modelData.year}`);
}
}
} }
} }
+58 -6
View File
@@ -1,3 +1,6 @@
pragma ComponentBehavior: Bound
import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Shapes import QtQuick.Shapes
@@ -34,6 +37,55 @@ Item {
onTriggered: Players.active?.positionChanged() onTriggered: Players.active?.positionChanged()
} }
Shape {
id: visualizer
readonly property real centerX: width / 2
readonly property real centerY: height / 2
property color colour: DynamicColors.palette.m3primary
readonly property real innerX: cover.implicitWidth / 2 + Appearance.spacing.small
readonly property real innerY: cover.implicitHeight / 2 + Appearance.spacing.small
anchors.fill: cover
anchors.margins: -Config.dashboard.sizes.mediaVisualiserSize
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 angle: modelData * 2 * Math.PI / Config.services.visualizerBars
readonly property real cos: Math.cos(angle)
readonly property real magnitude: value * Config.dashboard.sizes.mediaVisualiserSize
required property int modelData
readonly property real sin: Math.sin(angle)
readonly property real value: Math.max(1e-3, Math.min(1, Audio.cava.values[modelData]))
capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
startX: visualizer.centerX + (visualizer.innerX + strokeWidth / 2) * cos
strokeColor: DynamicColors.palette.m3primary
strokeWidth: 360 / Config.services.visualizerBars - Appearance.spacing.small / 4
startY: PathLine {
x: visualizer.centerX + (visualizer.innerX + visualizerBar.strokeWidth / 2 + visualizerBar.magnitude) * visualizerBar.cos
y: visualizer.centerY + (visualizer.innerY + visualizerBar.strokeWidth / 2 + visualizerBar.magnitude) * visualizerBar.sin
}
Behavior on strokeColor {
CAnim {
}
}
}
}
Shape { Shape {
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
@@ -136,31 +188,31 @@ Item {
width: parent.width - Appearance.padding.large * 4 width: parent.width - Appearance.padding.large * 4
} }
CustomText { MarqueeText {
id: album id: album
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: title.bottom anchors.top: title.bottom
anchors.topMargin: Appearance.spacing.small anchors.topMargin: Appearance.spacing.small
animate: true
color: DynamicColors.palette.m3outline color: DynamicColors.palette.m3outline
elide: Text.ElideRight
font.pointSize: Appearance.font.size.small font.pointSize: Appearance.font.size.small
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
pauseMs: 4000
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album") text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
width: parent.width - Appearance.padding.large * 4
} }
CustomText { MarqueeText {
id: artist id: artist
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: album.bottom anchors.top: album.bottom
anchors.topMargin: Appearance.spacing.small anchors.topMargin: Appearance.spacing.small
animate: true
color: DynamicColors.palette.m3secondary color: DynamicColors.palette.m3secondary
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
pauseMs: 4000
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist") text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
width: parent.width - Appearance.padding.large * 4
} }
Row { Row {
-1
View File
@@ -34,7 +34,6 @@ Item {
StateLayer { StateLayer {
function onClicked(): void { function onClicked(): void {
console.log(root.modelData.path);
Wallpapers.setWallpaper(root.modelData.path); Wallpapers.setWallpaper(root.modelData.path);
root.visibilities.launcher = false; root.visibilities.launcher = false;
} }
-2
View File
@@ -14,8 +14,6 @@ Item {
required property var wrapper required property var wrapper
Component.onCompleted: console.log(Networking.backend.toString())
ColumnLayout { ColumnLayout {
id: layout id: layout
@@ -74,7 +74,6 @@ CustomRect {
visible: Bluetooth.defaultAdapter ?? false visible: Bluetooth.defaultAdapter ?? false
onClicked: { onClicked: {
// console.log(Bluetooth.defaultAdapter)
const adapter = Bluetooth.defaultAdapter; const adapter = Bluetooth.defaultAdapter;
if (adapter) if (adapter)
adapter.enabled = !adapter.enabled; adapter.enabled = !adapter.enabled;
-2
View File
@@ -257,7 +257,6 @@ Scope {
onClicked: { onClicked: {
panelWindow.detailsOpen = !panelWindow.detailsOpen; panelWindow.detailsOpen = !panelWindow.detailsOpen;
console.log(panelWindow.detailsOpen);
} }
} }
@@ -300,7 +299,6 @@ Scope {
onClicked: { onClicked: {
root.shouldShow = false; root.shouldShow = false;
console.log(icon.source, icon.visible);
polkitAgent.flow.cancelAuthenticationRequest(); polkitAgent.flow.cancelAuthenticationRequest();
passInput.text = ""; passInput.text = "";
} }
-1
View File
@@ -14,7 +14,6 @@ Item {
anchors.fill: parent anchors.fill: parent
Component.onCompleted: { Component.onCompleted: {
console.log(root.source);
if (source) if (source)
Qt.callLater(() => one.update()); Qt.callLater(() => one.update());
} }
+4 -4
View File
@@ -3,10 +3,10 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED) pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED) pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
pkg_check_modules(Aubio IMPORTED_TARGET aubio REQUIRED) pkg_check_modules(Aubio IMPORTED_TARGET aubio REQUIRED)
# pkg_check_modules(Cava IMPORTED_TARGET libcava QUIET) pkg_check_modules(Cava IMPORTED_TARGET libcava QUIET)
# if(NOT Cava_FOUND) if(NOT Cava_FOUND)
# pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED) pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED)
# endif() endif()
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml") set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml")
qt_standard_project_setup(REQUIRES 6.9) qt_standard_project_setup(REQUIRES 6.9)