diff options
| author | subh <subh@subh.space> | 2026-04-04 10:34:46 +0530 |
|---|---|---|
| committer | subh <subh@subh.space> | 2026-04-04 10:34:46 +0530 |
| commit | 92811eb6050c2f2971c6ab8998b18d448ded35a0 (patch) | |
| tree | 356e3fecdf88cb6728f6df5222733e1aa8547ec2 /quickshell/mpd/shell.qml.bak | |
| parent | 314d760de1922128124f2a9be0494fd4f6f7effb (diff) | |
Departure from catppuccin to gruvboxmain
Diffstat (limited to 'quickshell/mpd/shell.qml.bak')
| -rw-r--r-- | quickshell/mpd/shell.qml.bak | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/quickshell/mpd/shell.qml.bak b/quickshell/mpd/shell.qml.bak new file mode 100644 index 0000000..be04cf0 --- /dev/null +++ b/quickshell/mpd/shell.qml.bak @@ -0,0 +1,470 @@ +import Quickshell +import Quickshell.Io +import QtQuick +import QtQuick.Layouts +ShellRoot { + + property color colBg: "#000000" + property color colFg: "#ffffff" + property color colMuted: "#313244" + property color colCyan: "#89dceb" + property color colPurple: "#cba6f7" + property color colRed: "#f38ba8" + property color colYellow: "#f9e2af" + property color colBlue: "#89b4fa" + property color colGreen: "#A3BE8C" + property string fontFamily: "Iosevka Nerd Font Propo" + property int fontSize: 16 + + + property string mpd_title: "" + property string mpd_artist: "" + property string mpd_elapsed: "0:00" + property string mpd_duration: "0:00" + property string mpd_file: "" + property real mpd_progress: 0.0 + property bool isPlaying: false + property bool isPaused: false + property bool isActive: isPlaying || isPaused + property bool isSeeking: false + property bool cardVisible: false + property string artPath: "/tmp/mpdrop_art.png" + property string artCache: "" + + function timeToSecs(t) { + var p = t.split(":") + if (p.length === 2) return parseInt(p[0]) * 60 + parseInt(p[1]) + if (p.length === 3) return parseInt(p[0]) * 3600 + parseInt(p[1]) * 60 + parseInt(p[2]) + return 0 + } + + // Art Extractor + + Process { + id: artProc + property string filePath: "" + command: ["sh", "-c", "ffmpeg -i \"" + Qt.musicFolder + filePath + "\" -an -vcodec copy /tm/mdrop_art.png -y 2>/dev/null"] + running: false + onExited: { + artCache = "" + artCache = artPath + } + } + + // File Path Folder + Process { + id: fileProc + command: ["mpc", "--format", "%file%", "current"] + stdout: StdioCollector { + onStreamFinished: { + var f = this.text.trim() + if (f !== "" && f !== mpd_file) { + mpd_file = f + artProc.filePath = f + artProc.running = false + artProc.running = true + } + } + } + } + + // Idle Watcher + + Process { + id: idleProc + command: ["mpc", "idlewait"] + running: true + onExited: { + statusProc.running = true + } + } + + // Status Fetcher + Process { + id: statusProc + command: ["mpc", "status", "--format", "%title%||%artist||%duration%"] + stdout: StdioCollector { + onStreamFinished: { + var lines = this.text.trim().split("\n") + if (lines.length >= 2) { + var meta = lines[0].split("||") + var newTitle = meta[0] || "Unknown" + + if (newTitle !== mpd_title) fileProc.running = true + + mpd_title = newTitle + mpd_artist = meta[1] || "" + mpd_duration = meta[2] || "0:00" + + var sl = lines[1] + isPlaying = sl.indexOf("[playing]") !== -1 + isPaused = sl.indexOf("[paused]") !== -1 + + var tm = sl.match(/(\d+:\d+)\/(\d+:\d+)/) + if (tm) { + mpd_elapsed = tm[1] + var total = timeToSecs(tm[2]) + if (!isSeeking) { + mpd_progress = total > 0 ? timeToSecs(tm[1]) / total : 0 + } + + + } + else { + mpd_title = ""; mpd_artist = "" + mpd_elapsed = "0:00"; mpd_duration = "0:00" + mpd_progress = 0; isPlaying = false; isPaused = false + } + } + } + } + onExited: idleProc.running = true +} + property real progressPerSecond: { + var total = timeToSecs(mpd_duration) + return total > 0 ? 1.0 / total : 0 + } + + Timer { + id: progressTimer + interval: 1000 + running: isPlaying && !isSeeking + repeat: true + onTriggered: { + mpd_progress = Math.min(1.0, mpd_progress + progressPerSecond) + var elapsed = Math.round(mpd_progress * timeToSecs(mpd_duration)) + var m = Math.floor(elapsed / 60) + var s = elapsed % 60 + mpd_elapsed = m + ":" + (s < 10 ? "0" + s : s) + } + } + + + Timer { + id: seekResetTimer + interval: 1100 + repeat: false + onTriggered: isSeeking = false + } + + // Control process + Process { + id: ctrlProc + property var args: ["toggle"] + command: ["mpc"].concat(args) + running: false + onExited: statusProc.running = true + } + + // Hover Card + PanelWindow { + visible: cardVisible && isActive + screen: Quickshell.screens[0] + exclusionMode: ExclusionMode.Ignore + anchors { bottom: true; left: true } + implicitWidth: 280 + implicitHeight: 320 + color: "transparent" + + Rectangle { + anchors.fill: parent + anchors.margin: 12 + radius: 12 + color: colBg + border.color: colMuted + border.width: 1 + + opacity: cardVisible ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 200 } } + + Column { + anchors.fill: parent + anchors.margin: 12 + spacing: 10 + + // Album Art + Rectangle { + width: parent.width + height: parent.width + radius: 8 + color: colMuted + clip: true + + + Image { + id: artImage + anchors.fill: parent + source: artCache !== "" ? "file://" + artCache : "" + fillMode: Image.PreserveAspectCrop + cache: false + smooth: true + + //Placeholder for when no art + Text { + anchors.centerIn: parent + text: "😼" + font.pixelSize: 48 + font.family: fontFamily + color: colMuted + visible: artImage.status !== Image.Ready + } + } + } + + // Title + Text { + text: mpd_title + color: colFg + font.pixelSize: 13 + font.family: fontFamily + font.bold: true + elide: Text.ElideRight + width: parent.width + } + + // Artist + Text { + text: mpd_artist + color: colMuted + font.pixelSize: 12 + font.family: fontFamily + elide: Text.ElideRight + width: parent.width + visible: mpd_artist !== "" + } + + // Progress Bar + Rectangle { + width: parent.width + height: 3 + radius: 2 + color: colMuted + + Rectangle: { + width: parent.width * mpd_progress + height: parent.height + radius: 2 + color: isPlaying ? colCyan : colYellow + Behavior on width { + enabled: !isSeeking + NumberAnimation { duration: 950; easing.type: Easing.Linear } + } + + } + } + + // Time + RowLayout { + width: parent.width + Text { + text: mpd_elapsed + color: colFg + font.pixelSize: 11 + font.family: fontFamily + } + Item { Layout.fillWidth: true } + Text { + text: mpd_duration + color: colMuted + font.pixelSize: 11 + font.family: fontFamily + } + + } + } + } + } + + // ── The bar ──────────────────────────────────────────────── + PanelWindow { + id: mainBar + visible: isActive + screen: Quickshell.screens[0] + exclusionMode: PanelWindow + anchors { bottom: true; left: true; right: true } + implicitHeight: 36 + color: colBg + + // hover Detection + HoverHandler { + id: barHover + onHoveredChanged: cardVisible = barHover.hovered + } + + + + Rectangle { + anchors.fill: parent + color: colBg + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: colMuted + } + RowLayout { + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 0 + // ── Music icon ───────────────────────────────── + Text { + text: isPaused ? "" : "" + color: isPaused ? colYellow : colCyan + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + Behavior on color { ColorAnimation { duration: 200 } } + } + Item { width: 8 } + // ── Title ────────────────────────────────────── + Text { + text: mpd_title || "Unknown" + color: colPurple + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + elide: Text.ElideRight + Layout.maximumWidth: 220 + } + // ── Separator + Artist ───────────────────────── + Rectangle { + Layout.preferredWidth: 1; Layout.preferredHeight: 16 + Layout.leftMargin: 8; Layout.rightMargin: 8 + color: colMuted + visible: mpd_artist !== "" + } + Text { + text: mpd_artist + color: colCyan + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + elide: Text.ElideRight + Layout.maximumWidth: 180 + visible: mpd_artist !== "" + } + // ── Separator ────────────────────────────────── + Rectangle { + Layout.preferredWidth: 1; Layout.preferredHeight: 16 + Layout.leftMargin: 8; Layout.rightMargin: 8 + color: colMuted + } + // ── Prev ─────────────────────────────────────── + Text { + text: "" + color: prevH.containsMouse ? colCyan : colFg + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + Layout.rightMargin: 10 + HoverHandler { id: prevH } + TapHandler { onTapped: { if (!ctrlProc.running) { ctrlProc.args = ["prev"]; ctrlProc.running = true } } } + Behavior on color { ColorAnimation { duration: 100 } } + } + // ── Play / Pause ─────────────────────────────── + Text { + text: isPlaying ? "" : "" + color: playH.containsMouse ? colPurple : colCyan + font.pixelSize: fontSize + 2 + font.family: fontFamily + font.bold: true + Layout.rightMargin: 10 + HoverHandler { id: playH } + TapHandler { onTapped: { if (!ctrlProc.running) { ctrlProc.args = ["toggle"]; ctrlProc.running = true } } } + Behavior on color { ColorAnimation { duration: 100 } } + } + // ── Next ─────────────────────────────────────── + Text { + text: "" + color: nextH.containsMouse ? colCyan : colFg + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + Layout.rightMargin: 10 + HoverHandler { id: nextH } + TapHandler { onTapped: { if (!ctrlProc.running) { ctrlProc.args = ["next"]; ctrlProc.running = true } } } + Behavior on color { ColorAnimation { duration: 100 } } + } + // ── Stop ─────────────────────────────────────── + Text { + text: "" + color: stopH.containsMouse ? colRed : colMuted + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + HoverHandler { id: stopH } + TapHandler { onTapped: { if (!ctrlProc.running) { ctrlProc.args = ["stop"]; ctrlProc.running = true } } } + Behavior on color { ColorAnimation { duration: 100 } } + } + // ── Separator ────────────────────────────────── + Rectangle { + Layout.preferredWidth: 1; Layout.preferredHeight: 16 + Layout.leftMargin: 8; Layout.rightMargin: 8 + color: colMuted + } + // ── Elapsed ──────────────────────────────────── + Text { + text: mpd_elapsed + color: colFg + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + Layout.rightMargin: 8 + } + // ── Progress bar ─────────────────────────────── + Rectangle { + id: progressTrack + Layout.fillWidth: true + height: 4 + radius: 2 + color: colMuted + + // Fill + Rectangle { + id: progressFill + width: progressTrack.width * mpd_progress + height: parent.height + radius: 2 + color: isPlaying ? colCyan : colYellow + Behavior on width { + enabled: !isSeeking + NumberAnimation { duration: 950; easing.type: Easing.Linear } + } + Behavior on color { ColorAnimation { duration: 300 } } + } + + // Seek — child of progressTrack so parent.width works + MouseArea { + anchors.fill: parent + anchors.topMargin: -6 + anchors.bottomMargin: -6 + cursorShape: Qt.PointingHandCursor + onClicked: (mouse) => { + if (!ctrlProc.running) { + var pct = Math.max(0, Math.min(1, mouse.x / progressTrack.width)) + var pctInt = Math.round(pct * 100) + isSeeking = true + mpd_progress = pct + ctrlProc.args = ["seek", pctInt + "%"] + ctrlProc.running = true + seekResetTimer.restart() + } + } + } + } + // ── Duration ─────────────────────────────────── + Text { + text: mpd_duration + color: colMuted + font.pixelSize: fontSize + font.family: fontFamily + font.bold: true + Layout.leftMargin: 8 + } + Item { width: 8 } + } + } + } +} |
