1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-10 07:25:37 -05:00

dd: add file name to wallpaper tab

This commit is contained in:
bbedward
2025-10-23 22:56:53 -04:00
parent 492c0e7ef7
commit 884b73599a

View File

@@ -1,10 +1,10 @@
import Qt.labs.folderlistmodel import Qt.labs.folderlistmodel
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io
import qs.Common import qs.Common
import qs.Modals.FileBrowser import qs.Modals.FileBrowser
import qs.Services import qs.Services
@@ -16,11 +16,10 @@ Item {
implicitWidth: 700 implicitWidth: 700
implicitHeight: 410 implicitHeight: 410
property var wallpaperList: []
property string wallpaperDir: "" property string wallpaperDir: ""
property int currentPage: 0 property int currentPage: 0
property int itemsPerPage: 16 property int itemsPerPage: 16
property int totalPages: Math.max(1, Math.ceil(wallpaperList.length / itemsPerPage)) property int totalPages: Math.max(1, Math.ceil(wallpaperFolderModel.count / itemsPerPage))
property bool active: false property bool active: false
property Item focusTarget: wallpaperGrid property Item focusTarget: wallpaperGrid
property Item tabBarItem: null property Item tabBarItem: null
@@ -28,6 +27,8 @@ Item {
property Item keyForwardTarget: null property Item keyForwardTarget: null
property int lastPage: 0 property int lastPage: 0
property bool enableAnimation: false property bool enableAnimation: false
property string homeDir: StandardPaths.writableLocation(StandardPaths.HomeLocation)
property string selectedFileName: ""
signal requestTabChange(int newIndex) signal requestTabChange(int newIndex)
@@ -36,6 +37,11 @@ Item {
enableAnimation = false enableAnimation = false
lastPage = currentPage lastPage = currentPage
} }
updateSelectedFileName()
}
onGridIndexChanged: {
updateSelectedFileName()
} }
onVisibleChanged: { onVisibleChanged: {
@@ -45,10 +51,7 @@ Item {
} }
Component.onCompleted: { Component.onCompleted: {
loadWallpapers() loadWallpaperDirectory()
if (visible && active) {
setInitialSelection()
}
} }
onActiveChanged: { onActiveChanged: {
@@ -59,16 +62,17 @@ Item {
function handleKeyEvent(event) { function handleKeyEvent(event) {
const columns = 4 const columns = 4
const rows = 4
const currentRow = Math.floor(gridIndex / columns)
const currentCol = gridIndex % columns const currentCol = gridIndex % columns
const visibleCount = wallpaperGrid.model.length const visibleCount = Math.min(itemsPerPage, wallpaperFolderModel.count - currentPage * itemsPerPage)
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
if (gridIndex >= 0) { if (gridIndex >= 0 && gridIndex < visibleCount) {
const item = wallpaperGrid.currentItem const absoluteIndex = currentPage * itemsPerPage + gridIndex
if (item && item.wallpaperPath) { if (absoluteIndex < wallpaperFolderModel.count) {
SessionData.setWallpaper(item.wallpaperPath) const filePath = wallpaperFolderModel.get(absoluteIndex, "filePath")
if (filePath) {
SessionData.setWallpaper(filePath.toString().replace(/^file:\/\//, ''))
}
} }
} }
return true return true
@@ -76,10 +80,8 @@ Item {
if (event.key === Qt.Key_Right) { if (event.key === Qt.Key_Right) {
if (gridIndex + 1 < visibleCount) { if (gridIndex + 1 < visibleCount) {
// Move right within current page
gridIndex++ gridIndex++
} else if (gridIndex === visibleCount - 1 && currentPage < totalPages - 1) { } else if (currentPage < totalPages - 1) {
// At last item in page, go to next page
gridIndex = 0 gridIndex = 0
currentPage++ currentPage++
} }
@@ -88,22 +90,19 @@ Item {
if (event.key === Qt.Key_Left) { if (event.key === Qt.Key_Left) {
if (gridIndex > 0) { if (gridIndex > 0) {
// Move left within current page
gridIndex-- gridIndex--
} else if (gridIndex === 0 && currentPage > 0) { } else if (currentPage > 0) {
// At first item in page, go to previous page (last item)
currentPage-- currentPage--
gridIndex = Math.min(itemsPerPage - 1, wallpaperList.length - currentPage * itemsPerPage - 1) const prevPageCount = Math.min(itemsPerPage, wallpaperFolderModel.count - currentPage * itemsPerPage)
gridIndex = prevPageCount - 1
} }
return true return true
} }
if (event.key === Qt.Key_Down) { if (event.key === Qt.Key_Down) {
if (gridIndex + columns < visibleCount) { if (gridIndex + columns < visibleCount) {
// Move down within current page
gridIndex += columns gridIndex += columns
} else if (gridIndex >= visibleCount - columns && currentPage < totalPages - 1) { } else if (currentPage < totalPages - 1) {
// In last row, go to next page
gridIndex = currentCol gridIndex = currentCol
currentPage++ currentPage++
} }
@@ -112,12 +111,10 @@ Item {
if (event.key === Qt.Key_Up) { if (event.key === Qt.Key_Up) {
if (gridIndex >= columns) { if (gridIndex >= columns) {
// Move up within current page
gridIndex -= columns gridIndex -= columns
} else if (gridIndex < columns && currentPage > 0) { } else if (currentPage > 0) {
// In first row, go to previous page (last row)
currentPage-- currentPage--
const prevPageCount = Math.min(itemsPerPage, wallpaperList.length - currentPage * itemsPerPage) const prevPageCount = Math.min(itemsPerPage, wallpaperFolderModel.count - currentPage * itemsPerPage)
const prevPageRows = Math.ceil(prevPageCount / columns) const prevPageRows = Math.ceil(prevPageCount / columns)
gridIndex = (prevPageRows - 1) * columns + currentCol gridIndex = (prevPageRows - 1) * columns + currentCol
gridIndex = Math.min(gridIndex, prevPageCount - 1) gridIndex = Math.min(gridIndex, prevPageCount - 1)
@@ -144,8 +141,9 @@ Item {
} }
if (event.key === Qt.Key_End && event.modifiers & Qt.ControlModifier) { if (event.key === Qt.Key_End && event.modifiers & Qt.ControlModifier) {
gridIndex = 0
currentPage = totalPages - 1 currentPage = totalPages - 1
const lastPageCount = Math.min(itemsPerPage, wallpaperFolderModel.count - currentPage * itemsPerPage)
gridIndex = Math.max(0, lastPageCount - 1)
return true return true
} }
@@ -153,40 +151,38 @@ Item {
} }
function setInitialSelection() { function setInitialSelection() {
if (!SessionData.wallpaperPath) { if (!SessionData.wallpaperPath || wallpaperFolderModel.count === 0) {
gridIndex = 0 gridIndex = 0
updateSelectedFileName()
Qt.callLater(() => { enableAnimation = true })
return return
} }
const startIndex = currentPage * itemsPerPage for (let i = 0; i < wallpaperFolderModel.count; i++) {
const endIndex = Math.min(startIndex + itemsPerPage, wallpaperList.length) const filePath = wallpaperFolderModel.get(i, "filePath")
const pageWallpapers = wallpaperList.slice(startIndex, endIndex) if (filePath && filePath.toString().replace(/^file:\/\//, '') === SessionData.wallpaperPath) {
const targetPage = Math.floor(i / itemsPerPage)
for (let i = 0; i < pageWallpapers.length; i++) { const targetIndex = i % itemsPerPage
if (pageWallpapers[i] === SessionData.wallpaperPath) { currentPage = targetPage
gridIndex = i gridIndex = targetIndex
updateSelectedFileName()
Qt.callLater(() => { enableAnimation = true })
return return
} }
} }
gridIndex = 0 gridIndex = 0
updateSelectedFileName()
Qt.callLater(() => { enableAnimation = true })
} }
onWallpaperListChanged: { function loadWallpaperDirectory() {
if (visible && active) {
setInitialSelection()
}
}
function loadWallpapers() {
const currentWallpaper = SessionData.wallpaperPath const currentWallpaper = SessionData.wallpaperPath
// Try current wallpaper path / fallback to wallpaperLastPath
if (!currentWallpaper || currentWallpaper.startsWith("#") || currentWallpaper.startsWith("we:")) { if (!currentWallpaper || currentWallpaper.startsWith("#") || currentWallpaper.startsWith("we:")) {
if (CacheData.wallpaperLastPath && CacheData.wallpaperLastPath !== "") { if (CacheData.wallpaperLastPath && CacheData.wallpaperLastPath !== "") {
wallpaperDir = CacheData.wallpaperLastPath wallpaperDir = CacheData.wallpaperLastPath
} else { } else {
wallpaperDir = "" wallpaperDir = ""
wallpaperList = []
} }
return return
} }
@@ -194,44 +190,51 @@ Item {
wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/')) wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'))
} }
function updateWallpaperList() { function updateSelectedFileName() {
if (!wallpaperFolderModel || wallpaperFolderModel.count === 0) { if (wallpaperFolderModel.count === 0) {
wallpaperList = [] selectedFileName = ""
currentPage = 0
gridIndex = 0
return return
} }
// Build list from FolderListModel const absoluteIndex = currentPage * itemsPerPage + gridIndex
const files = [] if (absoluteIndex < wallpaperFolderModel.count) {
for (let i = 0; i < wallpaperFolderModel.count; i++) { const filePath = wallpaperFolderModel.get(absoluteIndex, "filePath")
const filePath = wallpaperFolderModel.get(i, "filePath")
if (filePath) { if (filePath) {
// Remove file:// prefix if present const pathStr = filePath.toString().replace(/^file:\/\//, '')
const cleanPath = filePath.toString().replace(/^file:\/\//, '') selectedFileName = pathStr.substring(pathStr.lastIndexOf('/') + 1)
files.push(cleanPath) return
} }
} }
selectedFileName = ""
wallpaperList = files
const currentPath = SessionData.wallpaperPath
const selectedIndex = currentPath ? wallpaperList.indexOf(currentPath) : -1
if (selectedIndex >= 0) {
currentPage = Math.floor(selectedIndex / itemsPerPage)
gridIndex = selectedIndex % itemsPerPage
} else {
const maxPage = Math.max(0, Math.ceil(files.length / itemsPerPage) - 1)
currentPage = Math.min(Math.max(0, currentPage), maxPage)
gridIndex = 0
}
} }
Connections { Connections {
target: SessionData target: SessionData
function onWallpaperPathChanged() { function onWallpaperPathChanged() {
loadWallpapers() loadWallpaperDirectory()
if (visible && active) {
setInitialSelection()
}
}
}
Connections {
target: wallpaperFolderModel
function onCountChanged() {
if (wallpaperFolderModel.status === FolderListModel.Ready) {
if (visible && active) {
setInitialSelection()
}
updateSelectedFileName()
}
}
function onStatusChanged() {
if (wallpaperFolderModel.status === FolderListModel.Ready && wallpaperFolderModel.count > 0) {
if (visible && active) {
setInitialSelection()
}
updateSelectedFileName()
}
} }
} }
@@ -246,18 +249,6 @@ Item {
showDirs: false showDirs: false
sortField: FolderListModel.Name sortField: FolderListModel.Name
folder: wallpaperDir ? "file://" + wallpaperDir : "" folder: wallpaperDir ? "file://" + wallpaperDir : ""
onStatusChanged: {
if (status === FolderListModel.Ready) {
updateWallpaperList()
}
}
onCountChanged: {
if (status === FolderListModel.Ready) {
updateWallpaperList()
}
}
} }
Loader { Loader {
@@ -275,13 +266,11 @@ Item {
showHiddenFiles: false showHiddenFiles: false
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"] fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
allowStacking: true allowStacking: true
onFileSelected: (path) => { onFileSelected: (path) => {
// Set the selected wallpaper
const cleanPath = path.replace(/^file:\/\//, '') const cleanPath = path.replace(/^file:\/\//, '')
SessionData.setWallpaper(cleanPath) SessionData.setWallpaper(cleanPath)
// Extract directory from the selected file and load all wallpapers
const dirPath = cleanPath.substring(0, cleanPath.lastIndexOf('/')) const dirPath = cleanPath.substring(0, cleanPath.lastIndexOf('/'))
if (dirPath) { if (dirPath) {
wallpaperDir = dirPath wallpaperDir = dirPath
@@ -290,7 +279,7 @@ Item {
} }
close() close()
} }
onDialogClosed: { onDialogClosed: {
Qt.callLater(() => wallpaperBrowserLoader.active = false) Qt.callLater(() => wallpaperBrowserLoader.active = false)
} }
@@ -336,8 +325,15 @@ Item {
model: { model: {
const startIndex = currentPage * itemsPerPage const startIndex = currentPage * itemsPerPage
const endIndex = Math.min(startIndex + itemsPerPage, wallpaperList.length) const endIndex = Math.min(startIndex + itemsPerPage, wallpaperFolderModel.count)
return wallpaperList.slice(startIndex, endIndex) const items = []
for (let i = startIndex; i < endIndex; i++) {
const filePath = wallpaperFolderModel.get(i, "filePath")
if (filePath) {
items.push(filePath.toString().replace(/^file:\/\//, ''))
}
}
return items
} }
onModelChanged: { onModelChanged: {
@@ -359,8 +355,11 @@ Item {
Connections { Connections {
target: root target: root
function onGridIndexChanged() { function onGridIndexChanged() {
if (enableAnimation && wallpaperGrid.count > 0) { if (wallpaperGrid.count > 0) {
wallpaperGrid.currentIndex = gridIndex wallpaperGrid.currentIndex = gridIndex
if (!enableAnimation) {
wallpaperGrid.positionViewAtIndex(gridIndex, GridView.Contain)
}
} }
} }
} }
@@ -440,7 +439,6 @@ Item {
if (modelData) { if (modelData) {
SessionData.setWallpaper(modelData) SessionData.setWallpaper(modelData)
} }
// Don't steal focus - let mainContainer keep it for keyboard nav
} }
} }
} }
@@ -449,7 +447,7 @@ Item {
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
visible: wallpaperList.length === 0 visible: wallpaperFolderModel.count === 0
text: "No wallpapers found\n\nClick the folder icon below to browse" text: "No wallpapers found\n\nClick the folder icon below to browse"
font.pixelSize: 14 font.pixelSize: 14
color: Theme.outline color: Theme.outline
@@ -457,67 +455,84 @@ Item {
} }
} }
Row { Column {
width: parent.width width: parent.width
height: 50 height: 50
spacing: Theme.spacingS
Item {
width: (parent.width - controlsRow.width - browseButton.width - Theme.spacingS) / 2
height: parent.height
}
Row { Row {
id: controlsRow width: parent.width
anchors.verticalCenter: parent.verticalCenter height: 32
spacing: Theme.spacingS spacing: Theme.spacingS
DankActionButton { Item {
width: (parent.width - controlsRow.width - browseButton.width - Theme.spacingS) / 2
height: parent.height
}
Row {
id: controlsRow
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
iconName: "skip_previous" spacing: Theme.spacingS
iconSize: 20
buttonSize: 32 DankActionButton {
enabled: currentPage > 0 anchors.verticalCenter: parent.verticalCenter
opacity: enabled ? 1.0 : 0.3 iconName: "skip_previous"
onClicked: { iconSize: 20
if (currentPage > 0) { buttonSize: 32
currentPage-- enabled: currentPage > 0
opacity: enabled ? 1.0 : 0.3
onClicked: {
if (currentPage > 0) {
currentPage--
}
}
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: wallpaperFolderModel.count > 0 ? `${wallpaperFolderModel.count} wallpapers ${currentPage + 1} / ${totalPages}` : "No wallpapers"
font.pixelSize: 14
color: Theme.surfaceText
opacity: 0.7
}
DankActionButton {
anchors.verticalCenter: parent.verticalCenter
iconName: "skip_next"
iconSize: 20
buttonSize: 32
enabled: currentPage < totalPages - 1
opacity: enabled ? 1.0 : 0.3
onClicked: {
if (currentPage < totalPages - 1) {
currentPage++
}
} }
} }
} }
StyledText { DankActionButton {
id: browseButton
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: wallpaperList.length > 0 ? `${wallpaperList.length} wallpapers ${currentPage + 1} / ${totalPages}` : "No wallpapers" iconName: "folder_open"
font.pixelSize: 14 iconSize: 20
color: Theme.surfaceText buttonSize: 32
opacity: 0.7 opacity: 0.7
} onClicked: wallpaperBrowserLoader.active = true
DankActionButton {
anchors.verticalCenter: parent.verticalCenter
iconName: "skip_next"
iconSize: 20
buttonSize: 32
enabled: currentPage < totalPages - 1
opacity: enabled ? 1.0 : 0.3
onClicked: {
if (currentPage < totalPages - 1) {
currentPage++
}
}
} }
} }
DankActionButton { StyledText {
id: browseButton width: parent.width
anchors.verticalCenter: parent.verticalCenter height: 18
iconName: "folder_open" text: selectedFileName
iconSize: 20 font.pixelSize: 12
buttonSize: 32 color: Theme.surfaceText
opacity: 0.7 opacity: 0.5
onClicked: wallpaperBrowserLoader.active = true visible: selectedFileName !== ""
elide: Text.ElideMiddle
horizontalAlignment: Text.AlignHCenter
} }
} }
} }
} }