diff --git a/bar/mpris/Card.qml b/bar/mpris/Card.qml deleted file mode 100644 index a075de5..0000000 --- a/bar/mpris/Card.qml +++ /dev/null @@ -1,177 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import Qt5Compat.GraphicalEffects -import Quickshell -import "../.." -import "../../widgets" as Widgets - -Rectangle { - required property var player - - radius: 5 - color: "transparent" - implicitHeight: 220 - - RowLayout { - id: cardLayout - spacing: 15 - - anchors { - fill: parent - leftMargin: 10 - rightMargin: 10 - topMargin: 10 // Added top margin for better spacing - bottomMargin: 10 // Added bottom margin for better spacing - } - - Rectangle { - id: mprisImage - color: "transparent" - radius: 10 - width: 200 - height: 200 - Layout.alignment: Qt.AlignVCenter - visible: true - - Image { - anchors.fill: parent - source: player.trackArtUrl - sourceSize.width: 1024 - sourceSize.height: 1024 - fillMode: Image.PreserveAspectFit - - layer.enabled: true - layer.effect: OpacityMask { - source: Rectangle { - width: mprisImage.width - height: mprisImage.height - radius: 10 - color: "white" - } - - maskSource: Rectangle { - width: mprisImage.width - height: mprisImage.height - radius: 10 - color: "black" - } - - layer.enabled: true - layer.effect: DropShadow { - transparentBorder: true - spread: 0.02 - samples: 25 - color: "#80000000" - } - } - } - } - - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 5 - - Text { - text: player.trackArtist - color: "white" - font.pointSize: 13 - font.bold: true - horizontalAlignment: Text.AlignHCenter - Layout.fillWidth: true - elide: Text.ElideRight - } - - Text { - text: player.trackTitle - color: "white" - font.pointSize: 13 - horizontalAlignment: Text.AlignHCenter - Layout.fillWidth: true - elide: Text.ElideRight - } - - RowLayout { - spacing: 6 - - ColorQuantizer { - id: colorQuantizer - source: Qt.resolvedUrl(Media.trackedPlayer?.trackArtUrl ?? "") - depth: 0 - rescaleSize: 64 - } - - Text { - text: timeStr(player.position) - color: "white" - - font { - pointSize: 9 - bold: true - } - } - - Widgets.RoundSlider { - from: 0 - to: 1 - accentColor: colorQuantizer.colors[0] - //value: root.node.audio.volume - //onValueChanged: node.audio.volume = value - Layout.fillWidth: true - Layout.preferredHeight: 16 - } - - Text { - text: timeStr(player.length) - color: "white" - - font { - pointSize: 9 - bold: true - } - } - } - - // Music Controls - RowLayout { - spacing: 2 - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - Widgets.IconButton { - implicitSize: 36 - activeRectangle: false - padding: 4 - source: "root:resources/mpris/previous.svg" - onClicked: player.previous() - } - - Widgets.IconButton { - implicitSize: 36 - activeRectangle: false - padding: 4 - source: player?.isPlaying ? "root:resources/mpris/pause.svg" : "root:resources/mpris/play.svg" - onClicked: { - if (!player.canPlay) - return; - player.isPlaying ? player.pause() : player.play(); - } - } - - Widgets.IconButton { - implicitSize: 36 - activeRectangle: false - padding: 4 - source: "root:resources/mpris/next.svg" - onClicked: player.next() - } - } - } - } - - function timeStr(time: int): string { - const seconds = time % 60; - const minutes = Math.floor(time / 60); - - return `${minutes}:${seconds.toString().padStart(2, '0')}`; - } -} diff --git a/bar/mpris/Player.qml b/bar/mpris/Player.qml deleted file mode 100644 index e6c7837..0000000 --- a/bar/mpris/Player.qml +++ /dev/null @@ -1,151 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import Qt5Compat.GraphicalEffects -import Quickshell -import Quickshell.Services.Mpris -import "../.." - -PopupWindow { - id: root - width: mediaPlayerContainer.width + 10 - height: mediaPlayerContainer.height + 10 - color: "transparent" - visible: mediaPlayerContainer.opacity > 0 - - anchor.rect.x: parentWindow.width / 2 - width / 2 - anchor.rect.y: parentWindow.height - - function show() { - mediaPlayerContainer.opacity = 1; - } - - function hide() { - mediaPlayerContainer.opacity = 0; - } - - HoverHandler { - id: hoverHandler - enabled: true - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - onHoveredChanged: { - if (hovered == false) { - hide(); - } - } - } - - Rectangle { - id: mediaPlayerContainer - width: 500 - height: mediaPlayerColumn.height + 20 - color: ShellGlobals.colors.background - radius: 5 - opacity: 0 - anchors.centerIn: parent - layer.enabled: true - layer.effect: OpacityMask { - source: Rectangle { - width: mediaPlayerContainer.width - height: mediaPlayerContainer.height - radius: mediaPlayerContainer.radius - color: "white" - } - - maskSource: Rectangle { - width: mediaPlayerContainer.width - height: mediaPlayerContainer.height - radius: mediaPlayerContainer.radius - color: "black" - } - - layer.enabled: true - layer.effect: DropShadow { - transparentBorder: true - spread: 0.02 - samples: 25 - color: "#80000000" - } - } - - Behavior on opacity { - NumberAnimation { - duration: 300 - easing.type: Easing.OutCubic - } - } - - ColorQuantizer { - id: colorQuantizer - source: Qt.resolvedUrl(Media.trackedPlayer?.trackArtUrl ?? "") - depth: 2 - rescaleSize: 64 - - onColorsChanged: { - Media.colors = colors; - } - } - - ShaderEffect { - property color topLeftColor: colorQuantizer?.colors[0]?.lighter(1.2) ?? "white" - property color topRightColor: colorQuantizer?.colors[1]?.lighter(1.2) ?? "black" - property color bottomLeftColor: colorQuantizer?.colors[2]?.lighter(1.2) ?? "white" - property color bottomRightColor: colorQuantizer?.colors[3]?.lighter(1.2) ?? "black" - - anchors.fill: parent - fragmentShader: "root:/shaders/vertexgradient.frag.qsb" - vertexShader: "root:/shaders/vertexgradient.vert.qsb" - - Behavior on topLeftColor { - ColorAnimation { - duration: 500 - easing.type: Easing.InOutQuad - } - } - Behavior on topRightColor { - ColorAnimation { - duration: 500 - easing.type: Easing.InOutQuad - } - } - Behavior on bottomLeftColor { - ColorAnimation { - duration: 500 - easing.type: Easing.InOutQuad - } - } - Behavior on bottomRightColor { - ColorAnimation { - duration: 500 - easing.type: Easing.InOutQuad - } - } - } - - ColumnLayout { - id: mediaPlayerColumn - spacing: 10 - Layout.fillWidth: true - Layout.preferredWidth: parent.width - Layout.margins: 10 - implicitHeight: childrenRect.height - - anchors { - top: parent.top - left: parent.left - right: parent.right - margins: 10 - } - - // Media Cards - Repeater { - model: Mpris.players - - Card { - required property var modelData - player: modelData - Layout.fillWidth: true - } - } - } - } -} diff --git a/bar/mpris/Status.qml b/bar/mpris/Status.qml deleted file mode 100644 index 9d96f13..0000000 --- a/bar/mpris/Status.qml +++ /dev/null @@ -1,86 +0,0 @@ -import QtQuick -import Quickshell.Widgets -import Quickshell.Services.Mpris -import "../.." - -Item { - id: root - required property var bar - - width: statusInfo.width + 125 - height: parent.height - visible: Mpris.players.values.length != 0 - - Player { - id: mediaPlayer - anchor.window: bar - anchor.rect.x: parentWindow.width / 2 - width / 2 - anchor.rect.y: parentWindow.height - } - - MouseArea { - id: playButton - hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: mouse => { - if (mouse.button === Qt.LeftButton) { - if (mediaPlayer.visible) { - mediaPlayer.hide(); - } else { - mediaPlayer.show(); - } - } else { - if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null) - return; - - if (Media.trackedPlayer.isPlaying) - Media.trackedPlayer.pause(); - else - Media.trackedPlayer.play(); - } - } - - anchors.fill: parent - } - - Item { - id: statusInfo - width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width - height: parent.height - visible: Media.trackedPlayer != null - - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - top: parent.top - bottom: parent.botton - margins: 3.5 - } - - IconImage { - id: statusIcon - implicitSize: 13 - source: Media.trackedPlayer?.isPlaying ? "root:resources/mpris/pause.svg" : "root:resources/mpris/play.svg" - - anchors { - verticalCenter: parent.verticalCenter - right: nowPlayingText.left - rightMargin: 10 - } - } - - Text { - id: nowPlayingText - color: ShellGlobals.colors.text - text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}` - font.pointSize: 11 - width: Math.min(implicitWidth, 250) - elide: Text.ElideRight - - anchors { - verticalCenter: parent.verticalCenter - right: parent.right - } - } - } -} diff --git a/lockscreen/README.md b/lockscreen/README.md deleted file mode 100644 index 1926b9b..0000000 --- a/lockscreen/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Lockscreen - -This is a simple but functional lockscreen that follows the system color scheme. -The only authentication method it supports is a password. - -You can run the lockscreen with `quickshell -p shell.qml`. - -You can run the lockscreen in test mode (as a window) with `quickshell -p test.qml`. - -![](./image.png) diff --git a/lockscreen/image.png b/lockscreen/image.png deleted file mode 100644 index f9d25d3..0000000 Binary files a/lockscreen/image.png and /dev/null differ diff --git a/lockscreen/test.qml b/lockscreen/test.qml deleted file mode 100644 index 22dddb9..0000000 --- a/lockscreen/test.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick -import Quickshell - -ShellRoot { - LockContext { - id: lockContext - onUnlocked: Qt.quit(); - } - - FloatingWindow { - LockSurface { - anchors.fill: parent - context: lockContext - } - } - - // exit the example if the window closes - Connections { - target: Quickshell - - function onLastWindowClosed() { - Qt.quit(); - } - } -} diff --git a/bar/mpris/Media.qml b/mpris/Controller.qml similarity index 57% rename from bar/mpris/Media.qml rename to mpris/Controller.qml index 98ff93a..3d6e89f 100644 --- a/bar/mpris/Media.qml +++ b/mpris/Controller.qml @@ -1,13 +1,42 @@ pragma Singleton +pragma ComponentBehavior: Bound import QtQuick import Quickshell +import Quickshell.Io import Quickshell.Services.Mpris Singleton { id: root property MprisPlayer trackedPlayer - property var colors: ["white"] + + IpcHandler { + target: "mpris" + + function next(): void { + root.trackedPlayer.next(); + } + + function prev(): void { + root.trackedPlayer.previous(); + } + + function play(): void { + root.trackedPlayer.play(); + } + + function pause(): void { + root.trackedPlayer.pause(); + } + + function play_pause(): void { + if (root.trackedPlayer.isPlaying) { + root.trackedPlayer.pause(); + } else { + root.trackedPlayer.play(); + } + } + } Instantiator { model: Mpris.players @@ -31,8 +60,8 @@ Singleton { } } - if (trackedPlayer == null && Mpris.players.values.length != 0) { - trackedPlayer = Mpris.players.values[0]; + if (root.trackedPlayer == null && Mpris.players.values.length != 0) { + root.trackedPlayer = Mpris.players.values[0]; } } } @@ -43,4 +72,6 @@ Singleton { } } } + + function init() {} } diff --git a/shell.qml b/shell.qml index b5d2452..f50189f 100644 --- a/shell.qml +++ b/shell.qml @@ -5,6 +5,7 @@ import Quickshell import QtQuick import "bar" as Bar import "notifications" as Notifications +import "mpris" as Mpris import "volume-osd" as VolumeOSD import "settings" as Settings import "launcher" as Launcher @@ -13,13 +14,16 @@ import "wallpaper" as Wallpaper import "screencapture" as ScreenCapture ShellRoot { + // Singleton's that need to be loaded in some way Component.onCompleted: { Launcher.Controller.init(); Settings.Controller.init(); - Notifications.NotificationCenter.init(); ScreenCapture.Controller.init(); + Mpris.Controller.init(); + Notifications.NotificationCenter.init(); } + // Elements that need context from all screens Variants { model: Quickshell.screens @@ -31,13 +35,14 @@ ShellRoot { screen: scope.modelData } - LockScreen.Controller { - - } + LockScreen.Controller {} } } + // On activation components Notifications.Controller {} VolumeOSD.Controller {} + + // this is an exception... Wallpaper.Controller {} }