Make Wallpaper Selector scrollable
This commit is contained in:
parent
a867ae4bca
commit
8585c5c729
1 changed files with 228 additions and 219 deletions
|
|
@ -13,255 +13,264 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
ColumnLayout {
|
ScrollView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: Style.marginMedium * scaling
|
clip: true
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||||
|
contentWidth: parent.width
|
||||||
|
|
||||||
NText {
|
ColumnLayout {
|
||||||
text: "Wallpaper Selector"
|
width: parent.width
|
||||||
font.weight: Style.fontWeightBold
|
spacing: Style.marginMedium * scaling
|
||||||
color: Colors.accentSecondary
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Select a wallpaper from your configured directory"
|
|
||||||
color: Colors.textSecondary
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current wallpaper display
|
|
||||||
NText {
|
|
||||||
text: "Current Wallpaper"
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Colors.textPrimary
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 120 * scaling
|
|
||||||
radius: Style.radiusMedium * scaling
|
|
||||||
color: Colors.backgroundSecondary
|
|
||||||
border.color: Colors.outline
|
|
||||||
border.width: Math.max(1, Style.borderThin * scaling)
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Image {
|
NText {
|
||||||
id: currentWallpaperImage
|
text: "Wallpaper Selector"
|
||||||
anchors.fill: parent
|
font.weight: Style.fontWeightBold
|
||||||
anchors.margins: Style.marginSmall * scaling
|
color: Colors.accentSecondary
|
||||||
source: Wallpapers.currentWallpaper
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
asynchronous: true
|
|
||||||
cache: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback if no image
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Style.marginSmall * scaling
|
|
||||||
color: Colors.backgroundTertiary
|
|
||||||
radius: Style.radiusSmall * scaling
|
|
||||||
visible: currentWallpaperImage.status !== Image.Ready
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Style.marginSmall * scaling
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "image"
|
|
||||||
font.family: "Material Symbols Outlined"
|
|
||||||
font.pointSize: Style.fontSizeLarge * scaling
|
|
||||||
color: Colors.textSecondary
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "No wallpaper selected"
|
|
||||||
color: Colors.textSecondary
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wallpaper grid
|
|
||||||
NText {
|
|
||||||
text: "Available Wallpapers"
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Colors.textPrimary
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Click on a wallpaper to set it as your current wallpaper"
|
|
||||||
color: Colors.textSecondary
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: Settings.data.wallpaper.swww.enabled ?
|
|
||||||
"Wallpapers will change with " + Settings.data.wallpaper.swww.transitionType + " transition" :
|
|
||||||
"Wallpapers will change instantly"
|
|
||||||
color: Colors.textSecondary
|
|
||||||
font.pointSize: Style.fontSizeSmall * scaling
|
|
||||||
visible: Settings.data.wallpaper.swww.enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh button and status
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Style.marginSmall * scaling
|
|
||||||
|
|
||||||
NIconButton {
|
|
||||||
icon: "refresh"
|
|
||||||
tooltipText: "Refresh wallpaper list"
|
|
||||||
onClicked: {
|
|
||||||
Wallpapers.loadWallpapers()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Refresh"
|
text: "Select a wallpaper from your configured directory"
|
||||||
color: Colors.textSecondary
|
color: Colors.textSecondary
|
||||||
}
|
wrapMode: Text.WordWrap
|
||||||
}
|
|
||||||
|
|
||||||
// Wallpaper grid container
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
FolderListModel {
|
|
||||||
id: folderModel
|
|
||||||
folder: "file://" + (Settings.data.wallpaper.directory !== undefined ? Settings.data.wallpaper.directory : "")
|
|
||||||
nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"]
|
|
||||||
showDirs: false
|
|
||||||
sortField: FolderListModel.Name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GridView {
|
// Current wallpaper display
|
||||||
id: wallpaperGridView
|
NText {
|
||||||
anchors.fill: parent
|
text: "Current Wallpaper"
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Colors.textPrimary
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 120 * scaling
|
||||||
|
radius: Style.radiusMedium * scaling
|
||||||
|
color: Colors.backgroundSecondary
|
||||||
|
border.color: Colors.outline
|
||||||
|
border.width: Math.max(1, Style.borderThin * scaling)
|
||||||
clip: true
|
clip: true
|
||||||
model: folderModel
|
|
||||||
|
|
||||||
// Fixed 5 items per row - more aggressive sizing
|
|
||||||
property int itemSize: Math.floor((width - leftMargin - rightMargin - (4 * Style.marginSmall * scaling)) / 5)
|
|
||||||
|
|
||||||
cellWidth: Math.floor((width - leftMargin - rightMargin) / 5)
|
|
||||||
cellHeight: Math.floor(itemSize * 0.67) + Style.marginSmall * scaling
|
|
||||||
|
|
||||||
leftMargin: Style.marginSmall * scaling
|
|
||||||
rightMargin: Style.marginSmall * scaling
|
|
||||||
topMargin: Style.marginSmall * scaling
|
|
||||||
bottomMargin: Style.marginSmall * scaling
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
Image {
|
||||||
id: wallpaperItem
|
id: currentWallpaperImage
|
||||||
property string wallpaperPath: Settings.data.wallpaper.directory + "/" + fileName
|
anchors.fill: parent
|
||||||
property bool isSelected: wallpaperPath === Wallpapers.currentWallpaper
|
anchors.margins: Style.marginSmall * scaling
|
||||||
|
source: Wallpapers.currentWallpaper
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
asynchronous: true
|
||||||
|
cache: true
|
||||||
|
}
|
||||||
|
|
||||||
width: wallpaperGridView.itemSize
|
// Fallback if no image
|
||||||
height: Math.floor(wallpaperGridView.itemSize * 0.67)
|
Rectangle {
|
||||||
radius: Style.radiusMedium * scaling
|
anchors.fill: parent
|
||||||
color: isSelected ? Colors.accentPrimary : Colors.backgroundSecondary
|
anchors.margins: Style.marginSmall * scaling
|
||||||
border.color: isSelected ? Colors.accentSecondary : Colors.outline
|
color: Colors.backgroundTertiary
|
||||||
border.width: Math.max(1, Style.borderThin * scaling)
|
radius: Style.radiusSmall * scaling
|
||||||
clip: true
|
visible: currentWallpaperImage.status !== Image.Ready
|
||||||
|
|
||||||
Image {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: Style.marginTiny * scaling
|
spacing: Style.marginSmall * scaling
|
||||||
source: wallpaperPath
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
asynchronous: true
|
|
||||||
cache: true
|
|
||||||
smooth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selection indicator
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.margins: Style.marginTiny * scaling
|
|
||||||
width: 20 * scaling
|
|
||||||
height: 20 * scaling
|
|
||||||
radius: width / 2
|
|
||||||
color: Colors.accentPrimary
|
|
||||||
border.color: Colors.onAccent
|
|
||||||
border.width: Math.max(1, Style.borderThin * scaling)
|
|
||||||
visible: isSelected
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
anchors.centerIn: parent
|
text: "image"
|
||||||
text: "check"
|
|
||||||
font.family: "Material Symbols Outlined"
|
font.family: "Material Symbols Outlined"
|
||||||
font.pointSize: Style.fontSizeSmall * scaling
|
font.pointSize: Style.fontSizeLarge * scaling
|
||||||
color: Colors.onAccent
|
color: Colors.textSecondary
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Hover effect
|
NText {
|
||||||
Rectangle {
|
text: "No wallpaper selected"
|
||||||
anchors.fill: parent
|
color: Colors.textSecondary
|
||||||
color: Colors.textPrimary
|
Layout.alignment: Qt.AlignHCenter
|
||||||
opacity: mouseArea.containsMouse ? 0.1 : 0
|
|
||||||
radius: parent.radius
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 150 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
Wallpapers.changeWallpaper(wallpaperPath)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty state
|
NDivider {
|
||||||
Rectangle {
|
Layout.fillWidth: true
|
||||||
anchors.fill: parent
|
}
|
||||||
color: Colors.backgroundSecondary
|
|
||||||
radius: Style.radiusMedium * scaling
|
|
||||||
border.color: Colors.outline
|
|
||||||
border.width: Math.max(1, Style.borderThin * scaling)
|
|
||||||
visible: folderModel.count === 0 && !Wallpapers.scanning
|
|
||||||
|
|
||||||
ColumnLayout {
|
// Wallpaper grid
|
||||||
anchors.centerIn: parent
|
NText {
|
||||||
spacing: Style.marginMedium * scaling
|
text: "Available Wallpapers"
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Colors.textPrimary
|
||||||
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "folder_open"
|
text: "Click on a wallpaper to set it as your current wallpaper"
|
||||||
font.family: "Material Symbols Outlined"
|
color: Colors.textSecondary
|
||||||
font.pointSize: Style.fontSizeLarge * scaling
|
wrapMode: Text.WordWrap
|
||||||
color: Colors.textSecondary
|
}
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
NText {
|
||||||
|
text: Settings.data.wallpaper.swww.enabled ?
|
||||||
|
"Wallpapers will change with " + Settings.data.wallpaper.swww.transitionType + " transition" :
|
||||||
|
"Wallpapers will change instantly"
|
||||||
|
color: Colors.textSecondary
|
||||||
|
font.pointSize: Style.fontSizeSmall * scaling
|
||||||
|
visible: Settings.data.wallpaper.swww.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh button and status
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Style.marginSmall * scaling
|
||||||
|
|
||||||
|
NIconButton {
|
||||||
|
icon: "refresh"
|
||||||
|
tooltipText: "Refresh wallpaper list"
|
||||||
|
onClicked: {
|
||||||
|
Wallpapers.loadWallpapers()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "No wallpapers found"
|
text: "Refresh"
|
||||||
color: Colors.textSecondary
|
color: Colors.textSecondary
|
||||||
font.weight: Style.fontWeightBold
|
}
|
||||||
Layout.alignment: Qt.AlignHCenter
|
}
|
||||||
|
|
||||||
|
// Wallpaper grid container
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 400 * scaling
|
||||||
|
|
||||||
|
FolderListModel {
|
||||||
|
id: folderModel
|
||||||
|
folder: "file://" + (Settings.data.wallpaper.directory !== undefined ? Settings.data.wallpaper.directory : "")
|
||||||
|
nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"]
|
||||||
|
showDirs: false
|
||||||
|
sortField: FolderListModel.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: wallpaperGridView
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
model: folderModel
|
||||||
|
|
||||||
|
// Fixed 5 items per row - more aggressive sizing
|
||||||
|
property int itemSize: Math.floor((width - leftMargin - rightMargin - (4 * Style.marginSmall * scaling)) / 5)
|
||||||
|
|
||||||
|
cellWidth: Math.floor((width - leftMargin - rightMargin) / 5)
|
||||||
|
cellHeight: Math.floor(itemSize * 0.67) + Style.marginSmall * scaling
|
||||||
|
|
||||||
|
leftMargin: Style.marginSmall * scaling
|
||||||
|
rightMargin: Style.marginSmall * scaling
|
||||||
|
topMargin: Style.marginSmall * scaling
|
||||||
|
bottomMargin: Style.marginSmall * scaling
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: wallpaperItem
|
||||||
|
property string wallpaperPath: Settings.data.wallpaper.directory + "/" + fileName
|
||||||
|
property bool isSelected: wallpaperPath === Wallpapers.currentWallpaper
|
||||||
|
|
||||||
|
width: wallpaperGridView.itemSize
|
||||||
|
height: Math.floor(wallpaperGridView.itemSize * 0.67)
|
||||||
|
radius: Style.radiusMedium * scaling
|
||||||
|
color: isSelected ? Colors.accentPrimary : Colors.backgroundSecondary
|
||||||
|
border.color: isSelected ? Colors.accentSecondary : Colors.outline
|
||||||
|
border.width: Math.max(1, Style.borderThin * scaling)
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginTiny * scaling
|
||||||
|
source: wallpaperPath
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
asynchronous: true
|
||||||
|
cache: true
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selection indicator
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: Style.marginTiny * scaling
|
||||||
|
width: 20 * scaling
|
||||||
|
height: 20 * scaling
|
||||||
|
radius: width / 2
|
||||||
|
color: Colors.accentPrimary
|
||||||
|
border.color: Colors.onAccent
|
||||||
|
border.width: Math.max(1, Style.borderThin * scaling)
|
||||||
|
visible: isSelected
|
||||||
|
|
||||||
|
NText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "check"
|
||||||
|
font.family: "Material Symbols Outlined"
|
||||||
|
font.pointSize: Style.fontSizeSmall * scaling
|
||||||
|
color: Colors.onAccent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hover effect
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Colors.textPrimary
|
||||||
|
opacity: mouseArea.containsMouse ? 0.1 : 0
|
||||||
|
radius: parent.radius
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: 150 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
Wallpapers.changeWallpaper(wallpaperPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NText {
|
// Empty state
|
||||||
text: "Make sure your wallpaper directory is configured and contains image files"
|
Rectangle {
|
||||||
color: Colors.textSecondary
|
anchors.fill: parent
|
||||||
wrapMode: Text.WordWrap
|
color: Colors.backgroundSecondary
|
||||||
horizontalAlignment: Text.AlignHCenter
|
radius: Style.radiusMedium * scaling
|
||||||
Layout.preferredWidth: 300 * scaling
|
border.color: Colors.outline
|
||||||
|
border.width: Math.max(1, Style.borderThin * scaling)
|
||||||
|
visible: folderModel.count === 0 && !Wallpapers.scanning
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Style.marginMedium * scaling
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "folder_open"
|
||||||
|
font.family: "Material Symbols Outlined"
|
||||||
|
font.pointSize: Style.fontSizeLarge * scaling
|
||||||
|
color: Colors.textSecondary
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "No wallpapers found"
|
||||||
|
color: Colors.textSecondary
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "Make sure your wallpaper directory is configured and contains image files"
|
||||||
|
color: Colors.textSecondary
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.preferredWidth: 300 * scaling
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue