Files
Panama/config/dot/quickshell/modules/settings/StockAvatarPicker.qml
T

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
}
}