better widget style
This commit is contained in:
parent
484e1a8143
commit
e6a8808858
38
Colors.qml
38
Colors.qml
@ -5,25 +5,25 @@ import Quickshell
|
||||
Singleton {
|
||||
id: customColors
|
||||
// Core Backgrounds
|
||||
readonly property color background: "#0A0E14"
|
||||
readonly property color foreground: "#B3B1AD"
|
||||
readonly property color cursor: "#E6B450"
|
||||
readonly property color background: "#1A1B26"
|
||||
readonly property color foreground: "#C0CAF5"
|
||||
readonly property color cursor: "#C0CAF5"
|
||||
|
||||
// The 16 Colors of the Apocalypse
|
||||
readonly property color color0: "#0A0E14"
|
||||
readonly property color color1: "#FF3333"
|
||||
readonly property color color2: "#C2D94C"
|
||||
readonly property color color3: "#FF8F40"
|
||||
readonly property color color4: "#59C2FF"
|
||||
readonly property color color5: "#FFEE99"
|
||||
readonly property color color6: "#95E6CB"
|
||||
readonly property color color7: "#B3B1AD"
|
||||
readonly property color color8: "#4D5566"
|
||||
readonly property color color9: "#FF3333"
|
||||
readonly property color color10: "#C2D94C"
|
||||
readonly property color color11: "#FF8F40"
|
||||
readonly property color color12: "#59C2FF"
|
||||
readonly property color color13: "#FFEE99"
|
||||
readonly property color color14: "#95E6CB"
|
||||
readonly property color color15: "#B3B1AD"
|
||||
readonly property color color0: "#414868"
|
||||
readonly property color color1: "#F7768E"
|
||||
readonly property color color2: "#9ECE6A"
|
||||
readonly property color color3: "#E0AF68"
|
||||
readonly property color color4: "#7AA2F7"
|
||||
readonly property color color5: "#BB9AF7"
|
||||
readonly property color color6: "#7DCFFF"
|
||||
readonly property color color7: "#A9B1D6"
|
||||
readonly property color color8: "#414868"
|
||||
readonly property color color9: "#F7768E"
|
||||
readonly property color color10: "#9ECE6A"
|
||||
readonly property color color11: "#E0AF68"
|
||||
readonly property color color12: "#7AA2F7"
|
||||
readonly property color color13: "#BB9AF7"
|
||||
readonly property color color14: "#7DCFFF"
|
||||
readonly property color color15: "#C0CAF5"
|
||||
}
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs
|
||||
import "../../"
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
required property var modelData
|
||||
implicitHeight: 35
|
||||
//color: Colors.background
|
||||
implicitHeight: 34
|
||||
color: Colors.background
|
||||
anchors {
|
||||
top: true
|
||||
|
||||
@ -9,17 +9,41 @@ import Quickshell.Widgets
|
||||
import "../settings/"
|
||||
import "../../"
|
||||
|
||||
RowLayout {
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: mprisRepeater.implicitWidth + 10
|
||||
implicitHeight: 34
|
||||
|
||||
// 1. Let Repeater loop through the ObjectModel for us
|
||||
Repeater {
|
||||
id: mprisRepeater
|
||||
model: Mpris.players
|
||||
|
||||
delegate: RowLayout {
|
||||
id: delegateLayout
|
||||
delegate: Item {
|
||||
required property var modelData
|
||||
implicitHeight: 34
|
||||
implicitWidth: delegateLayout.implicitWidth
|
||||
MouseArea {
|
||||
id: playbackControl
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: mouse => {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
console.log("Left button press");
|
||||
}
|
||||
if (mouse.button == Qt.RightButton) {
|
||||
parent.modelData.togglePlaying();
|
||||
}
|
||||
}
|
||||
onDoubleClicked: mouse => {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
parent.modelData.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
id: delegateLayout
|
||||
// 2. 🕵️♀️ FILTER LOGIC
|
||||
// Check if this specific player is Spotify.
|
||||
// We verify 'modelData' exists and check the name.
|
||||
@ -32,11 +56,6 @@ RowLayout {
|
||||
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
|
||||
@ -45,6 +64,7 @@ RowLayout {
|
||||
spacing: 10
|
||||
|
||||
// 🖼️ ALBUM ART
|
||||
|
||||
ClippingWrapperRectangle {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
@ -53,7 +73,7 @@ RowLayout {
|
||||
IconImage {
|
||||
source: delegateLayout.artUrl // Access property from delegate
|
||||
asynchronous: true
|
||||
implicitSize: 24
|
||||
implicitSize: root.implicitHeight * 0.6
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,8 +102,7 @@ RowLayout {
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
|
||||
// ⏯️ CONTROLS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,23 +1,17 @@
|
||||
import QtQuick
|
||||
import Quickshell.Services.UPower
|
||||
import QtQuick.Layouts
|
||||
import "../settings/"
|
||||
import "../../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 80
|
||||
Text {
|
||||
id: powerProfile
|
||||
text: PowerProfile.toString(PowerProfiles.profile)
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: powerLayout.implicitWidth + 10
|
||||
implicitHeight: 34
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onClicked: mouse => {
|
||||
const modes = [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance];
|
||||
let current = PowerProfiles.profile;
|
||||
@ -30,5 +24,25 @@ Item {
|
||||
PowerProfiles.profile = modes[prevIndex];
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: powerLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
Text {
|
||||
id: powerProfile
|
||||
text: PowerProfile.toString(PowerProfiles.profile)
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize
|
||||
}
|
||||
Text {
|
||||
text: "Profile"
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize - 2
|
||||
opacity: 0.7
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,30 +1,29 @@
|
||||
import QtQuick
|
||||
import Quickshell.Services.Pipewire
|
||||
import Quickshell.Widgets
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
import "../../"
|
||||
import "../settings/"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: volRow.implicitWidth + 10
|
||||
implicitHeight: volRow.implicitHeight
|
||||
// grab the default speaker (Sink)
|
||||
property var sink: Pipewire.defaultAudioSink
|
||||
Process {
|
||||
id: pavu
|
||||
command: ["pavucontrol"] // The command and args list
|
||||
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: mouse => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
pavu.startDetached();
|
||||
}
|
||||
}
|
||||
anchors.fill: parent
|
||||
// Scroll to change volume (The fancy stuff!)
|
||||
}
|
||||
implicitWidth: styleLayout.implicitWidth + 10
|
||||
implicitHeight: 34
|
||||
property var sink: Pipewire.defaultAudioSink
|
||||
Process {
|
||||
id: pavu
|
||||
command: ["pavucontrol"] // The command and args list
|
||||
|
||||
}
|
||||
// Logic to pick the correct icon name
|
||||
function getVolumeIcon() {
|
||||
@ -50,29 +49,37 @@ Item {
|
||||
return "audio-volume-high";
|
||||
}
|
||||
|
||||
Row {
|
||||
id: volRow
|
||||
ColumnLayout {
|
||||
id: styleLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: 5
|
||||
spacing: 0
|
||||
Row {
|
||||
spacing: 10
|
||||
Text {
|
||||
PwObjectTracker {
|
||||
objects: Pipewire.ready ? root.sink : []
|
||||
}
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize
|
||||
text: Pipewire.ready ? Math.round(root.sink.audio.volume * 100) + "%" : "0%"
|
||||
}
|
||||
|
||||
IconImage {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 12
|
||||
height: 12
|
||||
|
||||
source: "root:/icons/" + root.getVolumeIcon() + "-symbolic.svg"
|
||||
}
|
||||
|
||||
Text {
|
||||
PwObjectTracker {
|
||||
objects: Pipewire.ready ? Pipewire.defaultAudioSink : []
|
||||
}
|
||||
width: 20
|
||||
Text {
|
||||
font.weight: 900
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize
|
||||
text: Pipewire.ready ? Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%" : "0%"
|
||||
font.pixelSize: Settings.fontSize - 2
|
||||
opacity: 0.7
|
||||
text: Pipewire.ready ? Pipewire.defaultAudioSink.nickname : "failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ import Quickshell.Hyprland
|
||||
import "."
|
||||
import "../../"
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import "../settings/"
|
||||
|
||||
WlrLayershell {
|
||||
id: root
|
||||
@ -29,7 +31,7 @@ WlrLayershell {
|
||||
right: true
|
||||
}
|
||||
margins {
|
||||
top: 30
|
||||
top: 45
|
||||
right: 10
|
||||
}
|
||||
|
||||
@ -52,7 +54,7 @@ WlrLayershell {
|
||||
ListView {
|
||||
id: notifList
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
anchors.margins: 0
|
||||
// Use 'spacing' to put gaps between notifications
|
||||
spacing: 10
|
||||
|
||||
@ -68,12 +70,12 @@ WlrLayershell {
|
||||
delegate: Item {
|
||||
id: notifyItem
|
||||
implicitWidth: ListView.view.width
|
||||
implicitHeight: 80 // Fixed height is usually better for icon layouts
|
||||
implicitHeight: 85 // Fixed height is usually better for icon layouts
|
||||
|
||||
required property var modelData
|
||||
Timer {
|
||||
id: timout
|
||||
interval: 3000000
|
||||
interval: 3000
|
||||
running: true
|
||||
onRunningChanged: notifyItem.modelData.dismiss()
|
||||
}
|
||||
@ -81,18 +83,24 @@ WlrLayershell {
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Colors.background
|
||||
radius: 10
|
||||
radius: 20
|
||||
border.color: Colors.color5
|
||||
border.width: 2
|
||||
|
||||
// 2. Use RowLayout to put Image | Text side-by-side
|
||||
RowLayout {
|
||||
id: fullLayout
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
spacing: 15
|
||||
spacing: 10
|
||||
|
||||
// 🖼️ THE IMAGE ON THE LEFT
|
||||
Image {
|
||||
ClippingWrapperRectangle {
|
||||
radius: 10
|
||||
implicitWidth: 64
|
||||
implicitHeight: 64
|
||||
visible: notifyItem.modelData.image !== ""
|
||||
IconImage {
|
||||
|
||||
// Use the image if available, otherwise hide this space?
|
||||
// Or you could use an icon fallback.
|
||||
@ -102,29 +110,28 @@ WlrLayershell {
|
||||
visible: notifyItem.modelData.image !== ""
|
||||
|
||||
// Fixed size for consistency
|
||||
sourceSize.width: 48
|
||||
sourceSize.height: 48
|
||||
Layout.preferredWidth: 48
|
||||
Layout.preferredHeight: 48
|
||||
implicitSize: 30
|
||||
|
||||
// Crop it nicely so it doesn't stretch
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
|
||||
// Optional: Cache it for performance
|
||||
asynchronous: true
|
||||
}
|
||||
}
|
||||
|
||||
// 📝 THE TEXT ON THE RIGHT
|
||||
ColumnLayout {
|
||||
id: textLayout
|
||||
// Take up all remaining width
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignTop // Center vertically
|
||||
Layout.alignment: Qt.AlignVCenter // Center vertically
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
text: notifyItem.modelData.summary
|
||||
color: Colors.foreground
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
@ -135,7 +142,9 @@ WlrLayershell {
|
||||
color: Colors.foreground
|
||||
|
||||
// Limit to 2 lines
|
||||
maximumLineCount: 2
|
||||
font.family: Settings.font
|
||||
font.pixelSize: Settings.fontSize - 2
|
||||
maximumLineCount: 3
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user