mpris widget in bar yippie ^_^
This commit is contained in:
parent
38173b9959
commit
d72adec2ef
@ -5,7 +5,7 @@ import Quickshell
|
||||
Singleton {
|
||||
id: customColors
|
||||
// Core Backgrounds
|
||||
readonly property color background: "#1A1B26"
|
||||
readonly property color background: "#24283B"
|
||||
readonly property color foreground: "#C0CAF5"
|
||||
readonly property color cursor: "#C0CAF5"
|
||||
|
||||
@ -17,7 +17,7 @@ Singleton {
|
||||
readonly property color color4: "#7AA2F7"
|
||||
readonly property color color5: "#BB9AF7"
|
||||
readonly property color color6: "#7DCFFF"
|
||||
readonly property color color7: "#A9B1D6"
|
||||
readonly property color color7: "#C0CAF5"
|
||||
readonly property color color8: "#414868"
|
||||
readonly property color color9: "#F7768E"
|
||||
readonly property color color10: "#9ECE6A"
|
||||
|
||||
@ -8,7 +8,7 @@ PanelWindow {
|
||||
required property var modelData
|
||||
implicitHeight: 30
|
||||
//color: Colors.background
|
||||
color: "black"
|
||||
color: Colors.background
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
@ -17,11 +17,13 @@ PanelWindow {
|
||||
|
||||
RowLayout {
|
||||
id: leftLayout
|
||||
spacing: 30
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Clock {
|
||||
Layout.leftMargin: 30
|
||||
}
|
||||
Mpris {}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@ -37,6 +39,7 @@ PanelWindow {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Volume {}
|
||||
Battery {}
|
||||
PowerProfiles {}
|
||||
SystemTray {
|
||||
Layout.rightMargin: 30
|
||||
}
|
||||
|
||||
@ -27,26 +27,5 @@ Item {
|
||||
color: Colors.foreground
|
||||
text: Math.round(UPower.displayDevice.percentage * 100) + "%"
|
||||
}
|
||||
Text {
|
||||
id: powerProfile
|
||||
text: PowerProfile.toString(PowerProfiles.profile)
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Appearance.font
|
||||
font.pixelSize: Appearance.fontSize
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
cursorShape: Qt.OpenHandCursor
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
const modes = [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance];
|
||||
let current = PowerProfiles.profile;
|
||||
let currentIndex = modes.indexOf(current);
|
||||
let nextIndex = (currentIndex + 1) % modes.length;
|
||||
PowerProfiles.profile = modes[nextIndex];
|
||||
PowerProfiles.profile = profiles[nextIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
134
modules/bar/Mpris.qml
Normal file
134
modules/bar/Mpris.qml
Normal file
@ -0,0 +1,134 @@
|
||||
// ⚠️ Ensure Colors is imported
|
||||
// import "../../"
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import qs
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
|
||||
// 1. Let Repeater loop through the ObjectModel for us
|
||||
Repeater {
|
||||
id: mprisRepeater
|
||||
model: Mpris.players
|
||||
|
||||
delegate: RowLayout {
|
||||
required property var modelData
|
||||
// 2. 🕵️♀️ FILTER LOGIC
|
||||
// Check if this specific player is Spotify.
|
||||
// We verify 'modelData' exists and check the name.
|
||||
property bool isSpotify: modelData && modelData.identity.toLowerCase().includes("spotify")
|
||||
|
||||
// 3. 👻 HIDE NON-SPOTIFY PLAYERS
|
||||
visible: isSpotify
|
||||
|
||||
// If hidden, take up ZERO space
|
||||
Layout.preferredWidth: isSpotify ? Math.min(implicitWidth, 400) : 0
|
||||
Layout.fillHeight: true
|
||||
|
||||
// 4. 🎵 USE 'modelData' DIRECTLY
|
||||
// property string title: modelData.metadata["xesam:title"] || "No Title"
|
||||
// property string artist: modelData.metadata["xesam:artist"] || "Unknown"
|
||||
// property string artUrl: modelData.metadata["mpris:artUrl"] || ""
|
||||
// property bool isPlaying: modelData.playbackStatus === MprisPlaybackStatus.Playing
|
||||
property string title: modelData.trackTitle
|
||||
property string artist: modelData.trackArtist
|
||||
property string artUrl: modelData.trackArtUrl
|
||||
property bool isPlaying: modelData.isPlaying
|
||||
|
||||
spacing: 8
|
||||
|
||||
// 🖼️ ALBUM ART
|
||||
Rectangle {
|
||||
Layout.preferredHeight: parent.height * 0.8
|
||||
Layout.preferredWidth: Layout.preferredHeight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
radius: 4
|
||||
color: Colors.background
|
||||
clip: true
|
||||
visible: parent.visible // Optimization
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: parent.parent.artUrl // Access property from delegate
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
sourceSize.width: 128
|
||||
sourceSize.height: 128
|
||||
}
|
||||
}
|
||||
|
||||
// 📝 TEXT INFO
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 0
|
||||
visible: parent.visible
|
||||
|
||||
Text {
|
||||
text: parent.parent.title
|
||||
color: Colors.foreground
|
||||
font.bold: true
|
||||
font.pixelSize: 12
|
||||
elide: Text.ElideRight
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
|
||||
Text {
|
||||
text: parent.parent.artist
|
||||
color: Colors.foreground
|
||||
opacity: 0.7
|
||||
font.pixelSize: 10
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
|
||||
// ⏯️ CONTROLS
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 8
|
||||
visible: parent.visible
|
||||
|
||||
// PREV
|
||||
Text {
|
||||
text: ""
|
||||
color: Colors.foreground
|
||||
font.pixelSize: 24
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
// Use modelData to control THIS player
|
||||
onClicked: modelData.previous()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
||||
// PLAY / PAUSE
|
||||
Text {
|
||||
text: parent.parent.isPlaying ? "" : ""
|
||||
color: Colors.foreground
|
||||
font.pixelSize: 24
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: modelData.playPause()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
||||
// NEXT
|
||||
Text {
|
||||
text: ""
|
||||
color: Colors.foreground
|
||||
font.pixelSize: 24
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: modelData.next()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
modules/bar/PowerProfiles.qml
Normal file
33
modules/bar/PowerProfiles.qml
Normal file
@ -0,0 +1,33 @@
|
||||
import QtQuick
|
||||
import Quickshell.Services.UPower
|
||||
import qs
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 80
|
||||
Text {
|
||||
id: powerProfile
|
||||
text: PowerProfile.toString(PowerProfiles.profile)
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Appearance.font
|
||||
font.pixelSize: Appearance.fontSize
|
||||
anchors.centerIn: parent
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
cursorShape: Qt.OpenHandCursor
|
||||
anchors.fill: parent
|
||||
onClicked: mouse => {
|
||||
const modes = [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance];
|
||||
let current = PowerProfiles.profile;
|
||||
let currentIndex = modes.indexOf(current);
|
||||
let nextIndex = (currentIndex + 1) % modes.length;
|
||||
let prevIndex = (currentIndex - 1) % modes.length;
|
||||
if (mouse.button == Qt.LeftButton)
|
||||
PowerProfiles.profile = modes[nextIndex];
|
||||
if (mouse.button == Qt.RightButton)
|
||||
PowerProfiles.profile = modes[prevIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,6 +73,8 @@ Item {
|
||||
|
||||
objects: Pipewire.defaultAudioSink
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 20
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Appearance.font
|
||||
|
||||
@ -59,7 +59,7 @@ WlrLayershell {
|
||||
required property var modelData
|
||||
Timer {
|
||||
id: timout
|
||||
interval: 5000
|
||||
interval: 30000
|
||||
running: true
|
||||
onRunningChanged: notifyItem.modelData.dismiss()
|
||||
}
|
||||
@ -67,27 +67,30 @@ WlrLayershell {
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Colors.background
|
||||
radius: 20
|
||||
radius: 10
|
||||
border.color: Colors.color5
|
||||
|
||||
// 2. Use RowLayout to put Image | Text side-by-side
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Row {
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
spacing: 15
|
||||
|
||||
// 🖼️ THE IMAGE ON THE LEFT
|
||||
Image {
|
||||
|
||||
// Use the image if available, otherwise hide this space?
|
||||
// Or you could use an icon fallback.
|
||||
source: notifyItem.modelData.image
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
// Hide if no image exists so text takes full width
|
||||
visible: notifyItem.modelData.image !== ""
|
||||
|
||||
// Fixed size for consistency
|
||||
Layout.preferredWidth: 48
|
||||
Layout.preferredHeight: 48
|
||||
width: 48
|
||||
height: 48
|
||||
|
||||
// Crop it nicely so it doesn't stretch
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
@ -100,7 +103,7 @@ WlrLayershell {
|
||||
ColumnLayout {
|
||||
// Take up all remaining width
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter // Center vertically
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignTop // Center vertically
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
@ -128,6 +131,8 @@ WlrLayershell {
|
||||
// (Your MouseArea for closing can still go here covering the whole thing)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: notifyItem.modelData.dismiss()
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import "." // <--- Ensures we can find ScreenCorners.qml
|
||||
import "../../"
|
||||
import "."
|
||||
|
||||
WlrLayershell {
|
||||
id: overlayRoot
|
||||
@ -29,7 +30,7 @@ WlrLayershell {
|
||||
ScreenCorners {
|
||||
// Adjust these to match your screen's aesthetic
|
||||
cornerRadius: 25
|
||||
cornerColor: "black"
|
||||
cornerColor: Colors.background
|
||||
shouldShow: true
|
||||
|
||||
// Ensure it stays on top of any other items in this window
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import qs
|
||||
|
||||
// removed "import qs.Commons" because you don't have it!
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@ -17,7 +14,7 @@ Item {
|
||||
|
||||
// What color should the corners be? (Usually black to match the bezel)
|
||||
// You can change this to "transparent" or a theme color if you want.
|
||||
property color cornerColor: Colors.background
|
||||
property color cornerColor
|
||||
|
||||
// Enable/Disable toggle
|
||||
property bool shouldShow: true
|
||||
@ -52,8 +49,7 @@ Item {
|
||||
readonly property real screenHeight: cornersShape.height
|
||||
|
||||
strokeWidth: -1 // No outline
|
||||
//fillColor: Colors.background
|
||||
fillColor: "black"
|
||||
fillColor: cornerColor
|
||||
|
||||
// Smooth fade if you toggle it
|
||||
|
||||
|
||||
@ -21,9 +21,8 @@ WlrLayershell {
|
||||
// 1. The StackView manages the images
|
||||
StackView {
|
||||
id: wallStack
|
||||
anchors.fill: parent
|
||||
implicitWidth: Screen.width
|
||||
implicitHeight: Screen.height
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
// 2. Define what a "Wallpaper" looks like
|
||||
Component {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user