aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--desktop/modules/appearance/WallpaperTab.qml116
1 files changed, 86 insertions, 30 deletions
diff --git a/desktop/modules/appearance/WallpaperTab.qml b/desktop/modules/appearance/WallpaperTab.qml
index af3c23b..3931fcb 100644
--- a/desktop/modules/appearance/WallpaperTab.qml
+++ b/desktop/modules/appearance/WallpaperTab.qml
@@ -28,6 +28,45 @@ Column {
// wallhaven-dl opens.
signal dismiss
+ // A folder's header row: chevron, name and count. The list draws one per
+ // folder, and the sticky copy over its top draws the folder in view.
+ component FolderHeader: Rectangle {
+ id: hdr
+ property string name
+ property int count
+ property bool open
+ signal clicked
+ radius: 8
+ color: Qt.alpha(Theme.surface, headerHover.hovered ? 0.8 : 0.4)
+
+ HoverHandler { id: headerHover }
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: hdr.clicked()
+ }
+
+ Text {
+ id: chevron
+ anchors { left: parent.left; leftMargin: 12; verticalCenter: parent.verticalCenter }
+ text: hdr.open ? "\uf077" : "\uf078"
+ font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 4 }
+ color: Theme.subtext
+ }
+ Text {
+ anchors { left: chevron.right; leftMargin: 10; verticalCenter: parent.verticalCenter }
+ text: hdr.name
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2; bold: true }
+ color: Theme.text
+ }
+ Text {
+ anchors { right: parent.right; rightMargin: 12; verticalCenter: parent.verticalCenter }
+ text: hdr.count
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ color: Theme.overlay
+ }
+ }
+
Connections {
target: Wallpapers
function onApplied(ok, message) {
@@ -234,38 +273,13 @@ Column {
width: ListView.view.width
height: start < 0 ? 40 : wallList.thumbHeight
- Rectangle {
+ FolderHeader {
visible: row.start < 0
anchors { fill: parent; topMargin: 6 }
- radius: 8
- color: Qt.alpha(Theme.surface, headerHover.hovered ? 0.8 : 0.4)
-
- HoverHandler { id: headerHover }
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: wallList.toggle(row.index)
- }
-
- Text {
- id: chevron
- anchors { left: parent.left; leftMargin: 12; verticalCenter: parent.verticalCenter }
- text: row.open ? "\uf077" : "\uf078"
- font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 4 }
- color: Theme.subtext
- }
- Text {
- anchors { left: chevron.right; leftMargin: 10; verticalCenter: parent.verticalCenter }
- text: row.group.name
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2; bold: true }
- color: Theme.text
- }
- Text {
- anchors { right: parent.right; rightMargin: 12; verticalCenter: parent.verticalCenter }
- text: row.group.files.length
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
- color: Theme.overlay
- }
+ name: row.group.name
+ count: row.group.files.length
+ open: row.open
+ onClicked: wallList.toggle(row.index)
}
Row {
@@ -340,6 +354,48 @@ Column {
}
}
}
+
+ // The folder of the topmost row, once its own header has
+ // scrolled off: a copy pinned over the list, so an open folder
+ // folds from anywhere in it. Folding returns to its header.
+ readonly property int topIndex: count, indexAt(0, contentY + 1)
+ readonly property int topStart: topIndex < 0 ? -1 : rows.get(topIndex).start
+ Rectangle {
+ parent: wallList
+ visible: wallList.topStart >= 0
+ width: wallList.width
+ height: 40
+ color: Theme.base
+
+ FolderHeader {
+ readonly property var group: wallList.topStart < 0 ? null
+ : wallList.group(rows.get(wallList.topIndex).key)
+ anchors { fill: parent; topMargin: 6 }
+ name: group?.name ?? ""
+ count: group?.files.length ?? 0
+ open: true
+ onClicked: {
+ let h = wallList.topIndex;
+ while (h > 0 && rows.get(h).start >= 0) h--;
+ wallList.toggle(h);
+ wallList.positionViewAtIndex(h, ListView.Beginning);
+ }
+ }
+ }
+
+ // The default wheel step moves a fraction of a thumbnail; a
+ // notch here moves one row. A touchpad's pixel delta is kept.
+ MouseArea {
+ parent: wallList
+ anchors.fill: parent
+ acceptedButtons: Qt.NoButton
+ onWheel: wheel => {
+ const d = wheel.pixelDelta.y !== 0 ? wheel.pixelDelta.y
+ : wheel.angleDelta.y / 120 * wallList.thumbHeight;
+ wallList.contentY = Math.max(wallList.originY, Math.min(
+ wallList.originY + wallList.contentHeight - wallList.height, wallList.contentY - d));
+ }
+ }
}
}
}