Add a displays widget for monitor layout and per-monitor wallpapers
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string directory: Quickshell.env("HOME") + "/wallpapers"
|
||||
property string assignedPath: ""
|
||||
property bool polling: false
|
||||
property var wallpapers: []
|
||||
|
||||
signal chosen(string path)
|
||||
|
||||
function refresh() {
|
||||
if (!listProc.running) listProc.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: listProc
|
||||
command: ["bash", "-c",
|
||||
'find "$1" -maxdepth 1 -type f \\( -iname "*.jpg" -o -iname "*.jpeg" ' +
|
||||
'-o -iname "*.png" -o -iname "*.webp" -o -iname "*.gif" \\) | sort',
|
||||
"--", root.directory]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var out = []
|
||||
var lines = String(text).split("\n")
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i].trim()
|
||||
if (line.length > 0) out.push(line)
|
||||
}
|
||||
root.wallpapers = out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPollingChanged: if (root.polling && root.wallpapers.length === 0) root.refresh()
|
||||
Component.onCompleted: root.refresh()
|
||||
|
||||
GridView {
|
||||
id: grid
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
cellWidth: Style.spaceReal(120)
|
||||
cellHeight: Style.spaceReal(80)
|
||||
model: root.wallpapers
|
||||
|
||||
delegate: Item {
|
||||
required property var modelData
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.spaceReal(3)
|
||||
radius: Style.cardRadius
|
||||
color: Util.alpha(Color.background, Style.cardFillAlpha)
|
||||
border.width: Style.cardBorderWidth
|
||||
border.color: modelData === root.assignedPath
|
||||
? Color.accent
|
||||
: (hover.hovered ? Color.blue : Util.alpha(Color.blue, Style.cardBorderAlpha))
|
||||
clip: true
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.cardBorderWidth
|
||||
source: Util.fileUrl(modelData)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
cache: true
|
||||
sourceSize.width: Math.round(Style.spaceReal(120) * 1.5)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: Style.cardBorderWidth
|
||||
height: caption.implicitHeight + Style.spaceReal(4)
|
||||
visible: hover.hovered || modelData === root.assignedPath
|
||||
color: Util.alpha(Color.background, 0.8)
|
||||
|
||||
Text {
|
||||
id: caption
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Style.spaceReal(6)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideMiddle
|
||||
text: String(modelData).replace(/^.*\//, "")
|
||||
textFormat: Text.PlainText
|
||||
color: Color.foreground
|
||||
font.family: Style.font.family
|
||||
font.pixelSize: Style.font.bodySmall
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hover
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: root.chosen(String(modelData))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: root.wallpapers.length === 0
|
||||
text: "No images in " + root.directory
|
||||
textFormat: Text.PlainText
|
||||
color: Util.alpha(Color.foreground, 0.6)
|
||||
font.family: Style.font.family
|
||||
font.pixelSize: Style.font.bodySmall
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user