117 lines
3.7 KiB
QML
117 lines
3.7 KiB
QML
// The pictures already on the machine, offered before the file chooser.
|
|
//
|
|
// /usr/share/pixmaps/faces is what GNOME's Users panel shows first, and it is
|
|
// the answer for most people: a picture that is already the right shape, needs
|
|
// no cropping, and costs one click. The file chooser stays right beside it for
|
|
// everyone else, so choosing a photo is not a second-class path -- it is simply
|
|
// the one that needs a crop step afterwards.
|
|
//
|
|
// An empty gallery is a normal state on a machine with no faces package
|
|
// installed, and says so rather than rendering an empty strip.
|
|
|
|
import QtQuick
|
|
import Quickshell.Widgets
|
|
import qs.config
|
|
|
|
Column {
|
|
id: root
|
|
|
|
// [{ name, path }] -- whatever the helper found, in the order it found it.
|
|
property var avatars: []
|
|
property bool enabled: true
|
|
|
|
signal picked(path: string)
|
|
signal fileRequested
|
|
|
|
width: parent ? parent.width : 620
|
|
spacing: 10
|
|
bottomPadding: 6
|
|
|
|
Flow {
|
|
width: parent.width
|
|
spacing: 8
|
|
|
|
Repeater {
|
|
model: root.avatars
|
|
|
|
delegate: Item {
|
|
id: tile
|
|
|
|
required property var modelData
|
|
|
|
readonly property string path: String(tile.modelData?.path ?? "")
|
|
|
|
width: 46
|
|
height: 46
|
|
|
|
ClippingRectangle {
|
|
anchors.fill: parent
|
|
anchors.margins: 2
|
|
radius: width / 2
|
|
color: Theme.alpha(Theme.fg, 0.08)
|
|
|
|
Image {
|
|
anchors.fill: parent
|
|
source: tile.path === "" ? "" : "file://" + tile.path
|
|
fillMode: Image.PreserveAspectCrop
|
|
asynchronous: true
|
|
sourceSize.width: 96
|
|
sourceSize.height: 96
|
|
}
|
|
}
|
|
|
|
// The ring is its own item rather than a border on the clipping
|
|
// rectangle: that one clips its children and does not carry a
|
|
// border group of its own.
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: width / 2
|
|
color: "transparent"
|
|
border.width: tileHover.hovered ? 2 : 1
|
|
border.color: tileHover.hovered
|
|
? Theme.alpha(Theme.accent, 0.7)
|
|
: Theme.alpha(Theme.fg, 0.1)
|
|
}
|
|
|
|
HoverHandler {
|
|
id: tileHover
|
|
enabled: root.enabled
|
|
cursorShape: Qt.PointingHandCursor
|
|
}
|
|
|
|
TapHandler {
|
|
enabled: root.enabled && tile.path !== ""
|
|
onTapped: root.picked(tile.path)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Wrapped so it sits on the tiles' centre line rather than on their top
|
|
// edge: Flow lays children out by their own height, and the button is
|
|
// fifteen pixels shorter than a picture.
|
|
Item {
|
|
width: chooseFile.implicitWidth
|
|
height: 46
|
|
|
|
SettingsButton {
|
|
id: chooseFile
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: "Choose a file…"
|
|
enabled: root.enabled
|
|
onClicked: root.fileRequested()
|
|
}
|
|
}
|
|
}
|
|
|
|
Text {
|
|
width: parent.width
|
|
visible: root.avatars.length === 0
|
|
text: "No pictures are installed on this machine, so a file of your own is the only choice here."
|
|
color: Theme.fgDim
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
}
|