From 399f69a68a276075977d115c22fe6372b1dc39dd Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Wed, 27 Aug 2025 11:34:56 -0400 Subject: [PATCH 1/3] styled slider --- components/StyledSlider.qml | 33 +++++++++++++++++++++++++++++++++ modules/storybook/Storybook.qml | 13 +++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 components/StyledSlider.qml diff --git a/components/StyledSlider.qml b/components/StyledSlider.qml new file mode 100644 index 0000000..644d024 --- /dev/null +++ b/components/StyledSlider.qml @@ -0,0 +1,33 @@ +import qs.config +import QtQuick +import QtQuick.Controls + +Slider { + id: control + + height: 24 + + background: Rectangle { + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: control.height + width: control.availableWidth + height: implicitHeight + radius: 8 + color: Theme.palette.base100 + + Rectangle { + width: control.visualPosition * parent.width + Behavior on width { + NumberAnimation { + duration: 75 + } + } + height: parent.height + color: Theme.palette.primary + radius: 8 + } + } + handle: null +} diff --git a/modules/storybook/Storybook.qml b/modules/storybook/Storybook.qml index 08f9538..f2565dc 100644 --- a/modules/storybook/Storybook.qml +++ b/modules/storybook/Storybook.qml @@ -69,6 +69,19 @@ StyledWindow { } } + ColumnLayout { + StyledText { + text: "Slider" + font.pixelSize: 18 + } + StyledSlider { + id: slider + from: 0 + to: 100 + value: 50 + } + } + ColumnLayout { StyledText { text: "Drawer" From e01096691fde987bac3bd316fe4036022ea65278 Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Wed, 27 Aug 2025 12:00:20 -0400 Subject: [PATCH 2/3] update mpris with slider --- modules/bar/components/Mpris.qml | 65 +++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/modules/bar/components/Mpris.qml b/modules/bar/components/Mpris.qml index 675a1b9..6ab1275 100644 --- a/modules/bar/components/Mpris.qml +++ b/modules/bar/components/Mpris.qml @@ -1,13 +1,17 @@ pragma ComponentBehavior: Bound +import qs.components import qs.config import qs.services import qs.widgets import QtQuick +import QtQuick.Layouts StyledButton { id: root + padding: 6 + onClicked: { if (!Mpris.active.canTogglePlaying) { return; @@ -19,29 +23,54 @@ StyledButton { } } - content: StyledText { - id: text - text: `${Mpris.active?.isPlaying ? "" : ""} ${Mpris.active?.trackTitle} - ${Mpris.active?.trackArtist}` + content: ColumnLayout { + id: content - font.pixelSize: Dimensions.mpris.fontSize + spacing: 0 - states: State { - name: "hovered" - when: root.containsMouse - PropertyChanges { - text { - color: Theme.palette.base300 + implicitWidth: text.width + implicitHeight: text.height + StyledText { + id: text + text: `${Mpris.active?.isPlaying ? "" : ""} ${Mpris.active?.trackTitle} - ${Mpris.active?.trackArtist}` + + font.pixelSize: Dimensions.mpris.fontSize + + states: State { + name: "hovered" + when: root.containsMouse + PropertyChanges { + text { + color: Theme.palette.primarycontent + } + } + } + transitions: Transition { + from: "" + to: "hovered" + reversible: true + ColorAnimation { + properties: "color" + duration: 100 + easing.type: Easing.InOutCubic } } } - transitions: Transition { - from: "" - to: "hovered" - reversible: true - ColorAnimation { - properties: "color" - duration: 200 - easing.type: Easing.InOutCubic + StyledSlider { + from: 0 + to: Mpris.active?.length ?? 0 + value: Mpris.active?.position + implicitHeight: 6 + Layout.fillWidth: true + onMoved: { + Mpris.active.position = value; + } + + Timer { + running: Mpris.active?.isPlaying + interval: 1000 + repeat: true + onTriggered: Mpris.active?.positionChanged() } } } From 95d3eb2bcc63ee6eea1945ae62cf08edd737ca23 Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Wed, 27 Aug 2025 12:43:56 -0400 Subject: [PATCH 3/3] basic mpris controller --- components/MprisController.qml | 99 +++++++++++++++++++++++++++++++++ constants/Icons.qml | 2 + modules/storybook/Storybook.qml | 10 ++++ 3 files changed, 111 insertions(+) create mode 100644 components/MprisController.qml diff --git a/components/MprisController.qml b/components/MprisController.qml new file mode 100644 index 0000000..6446666 --- /dev/null +++ b/components/MprisController.qml @@ -0,0 +1,99 @@ +pragma ComponentBehavior: Bound + +import qs.components +import qs.config +import qs.constants +import qs.widgets +import QtQuick +import QtQuick.Layouts +import Quickshell.Services.Mpris +import Quickshell.Widgets + +WrapperRectangle { + id: root + required property MprisPlayer player + + color: Theme.palette.base200 + radius: 8 + margin: 16 + + ColumnLayout { + + spacing: 12 + + implicitWidth: 800 + + StyledText { + Layout.alignment: Qt.AlignHCenter + text: { + if (root.player.identity) { + const words = root.player.identity.split("-"); + const capitalized = words.map(val => String(val).charAt(0).toUpperCase() + String(val).slice(1)); + console.log(capitalized); + return capitalized.join(" "); + } + return root.player.desktopEntry ?? root.player.dbusName ?? "unknown"; + } + font.pixelSize: 20 + } + + StyledText { + id: text + Layout.alignment: Qt.AlignHCenter + text: `${root.player.trackTitle} - ${root.player.trackArtist}` + font.pixelSize: Dimensions.mpris.fontSize + } + + RowLayout { + Layout.alignment: Qt.AlignHCenter + StyledButton { + id: backButton + content: LucideIcon { + color: backButton.containsMouse ? Theme.palette.primarycontent : Theme.palette.basecontent + text: Icons.skipBack + } + onClicked: { + root.player.previous(); + } + } + StyledButton { + id: playPauseButton + content: LucideIcon { + color: playPauseButton.containsMouse ? Theme.palette.primarycontent : Theme.palette.basecontent + text: root.player.isPlaying ? Icons.square : Icons.play + } + onClicked: { + root.player.isPlaying = !root.player.isPlaying; + } + } + StyledButton { + id: forwardButton + content: LucideIcon { + color: forwardButton.containsMouse ? Theme.palette.primarycontent : Theme.palette.basecontent + text: Icons.skipForward + } + onClicked: { + root.player.next(); + } + } + } + + StyledSlider { + from: 0 + to: root.player.length ?? 0 + value: root.player.position + implicitHeight: 6 + Layout.fillWidth: true + onMoved: { + root.player.position = value; + } + + Timer { + running: root.player.isPlaying + interval: 1000 + repeat: true + onTriggered: root.player.positionChanged() + } + } + } +} diff --git a/constants/Icons.qml b/constants/Icons.qml index 3311396..2e077d2 100644 --- a/constants/Icons.qml +++ b/constants/Icons.qml @@ -19,6 +19,8 @@ Singleton { property string memoryStick: "\u{E44a}" property string play: "\u{E140}" property string search: "\u{E155}" + property string skipBack: "\u{E163}" + property string skipForward: "\u{E164}" property string stop: "\u{E132}" property string square: "\u{E16B}" property string wifiOff: "\u{E1af}" diff --git a/modules/storybook/Storybook.qml b/modules/storybook/Storybook.qml index f2565dc..402c3b9 100644 --- a/modules/storybook/Storybook.qml +++ b/modules/storybook/Storybook.qml @@ -82,6 +82,16 @@ StyledWindow { } } + ColumnLayout { + StyledText { + text: "Mpris Controller" + font.pixelSize: 18 + } + MprisController { + player: Mpris.active ?? null + } + } + ColumnLayout { StyledText { text: "Drawer"