wallpaper selector: unfuck grid placement

This commit is contained in:
end-4
2025-08-23 10:13:52 +07:00
parent 767e35851b
commit 0e2eea7555
3 changed files with 81 additions and 132 deletions
@@ -343,6 +343,8 @@ Singleton {
property real baseVerticalBarWidth: 46 property real baseVerticalBarWidth: 46
property real verticalBarWidth: Config.options.bar.cornerStyle === 1 ? property real verticalBarWidth: Config.options.bar.cornerStyle === 1 ?
(baseVerticalBarWidth + root.sizes.hyprlandGapsOut * 2) : baseVerticalBarWidth (baseVerticalBarWidth + root.sizes.hyprlandGapsOut * 2) : baseVerticalBarWidth
property real wallpaperSelectorWidth: 1000
property real wallpaperSelectorHeight: 580
} }
syntaxHighlightingTheme: root.m3colors.darkmode ? "Monokai" : "ayu Light" syntaxHighlightingTheme: root.m3colors.darkmode ? "Monokai" : "ayu Light"
@@ -28,12 +28,7 @@ Scope {
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
color: "transparent" color: "transparent"
anchors { anchors.top: true
top: true
bottom: true
left: true
right: true
}
margins { margins {
top: Appearance.sizes.barHeight + Appearance.sizes.hyprlandGapsOut top: Appearance.sizes.barHeight + Appearance.sizes.hyprlandGapsOut
} }
@@ -42,6 +37,9 @@ Scope {
item: content item: content
} }
implicitHeight: Appearance.sizes.wallpaperSelectorHeight
implicitWidth: Appearance.sizes.wallpaperSelectorWidth
HyprlandFocusGrab { // Click outside to close HyprlandFocusGrab { // Click outside to close
id: grab id: grab
windows: [ panelWindow ] windows: [ panelWindow ]
@@ -54,8 +52,7 @@ Scope {
WallpaperSelectorContent { WallpaperSelectorContent {
id: content id: content
anchors { anchors {
top: parent.top fill: parent
horizontalCenter: parent.horizontalCenter
} }
} }
} }
@@ -15,8 +15,7 @@ import Quickshell.Hyprland
Item { Item {
id: root id: root
property int columns: 4 property int columns: 4
property int thumbnailWidth: 256 property real previewAspectRatio: 16 / 9
property int thumbnailHeight: 144
implicitHeight: columnLayout.implicitHeight implicitHeight: columnLayout.implicitHeight
implicitWidth: columnLayout.implicitWidth implicitWidth: columnLayout.implicitWidth
property var filteredWallpapers: Wallpapers.wallpapers property var filteredWallpapers: Wallpapers.wallpapers
@@ -63,13 +62,13 @@ Item {
ColumnLayout { ColumnLayout {
id: columnLayout id: columnLayout
anchors.horizontalCenter: parent.horizontalCenter anchors.fill: parent
anchors.top: parent.top spacing: -Appearance.sizes.elevationMargin
spacing: 8
Item { // Search box Item {
implicitHeight: filterField.implicitHeight // Search box
implicitWidth: filterField.implicitWidth implicitHeight: filterField.implicitHeight + Appearance.sizes.elevationMargin * 2
implicitWidth: filterField.implicitWidth + Appearance.sizes.elevationMargin * 2
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
StyledRectangularShadow { StyledRectangularShadow {
@@ -78,7 +77,11 @@ Item {
TextField { TextField {
id: filterField id: filterField
implicitHeight: 40 anchors {
fill: parent
margins: Appearance.sizes.elevationMargin
}
implicitHeight: 44
implicitWidth: Appearance.sizes.searchWidth implicitWidth: Appearance.sizes.searchWidth
padding: 10 padding: 10
placeholderText: "Search wallpapers..." placeholderText: "Search wallpapers..."
@@ -94,7 +97,7 @@ Item {
font.pixelSize: Appearance.font.pixelSize.normal font.pixelSize: Appearance.font.pixelSize.normal
onTextChanged: { onTextChanged: {
root.filterQuery = text root.filterQuery = text;
} }
Keys.onPressed: event => { Keys.onPressed: event => {
@@ -133,48 +136,38 @@ Item {
Item { // The grid Item { // The grid
id: wallpaperGrid id: wallpaperGrid
Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true
implicitWidth: wallpaperGridBackground.implicitWidth Layout.fillHeight: true
implicitHeight: wallpaperGridBackground.implicitHeight implicitWidth: wallpaperGridBackground.implicitWidth + Appearance.sizes.elevationMargin * 2
implicitHeight: wallpaperGridBackground.implicitHeight + Appearance.sizes.elevationMargin * 2
StyledRectangularShadow { StyledRectangularShadow {
target: wallpaperGridBackground target: wallpaperGridBackground
} }
Rectangle { Rectangle {
id: wallpaperGridBackground id: wallpaperGridBackground
color: Appearance.colors.colLayer0 anchors {
radius: Appearance.rounding.screenRounding fill: parent
margins: Appearance.sizes.elevationMargin
}
focus: true
border.width: 1 border.width: 1
border.color: Appearance.colors.colLayer0Border border.color: Appearance.colors.colLayer0Border
focus: true color: Appearance.colors.colLayer0
radius: Appearance.rounding.screenRounding
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: wallpaperGridBackground.width
height: wallpaperGridBackground.height
radius: wallpaperGridBackground.radius
}
}
property int calculatedRows: Math.ceil(grid.count / grid.columns) property int calculatedRows: Math.ceil(grid.count / grid.columns)
implicitWidth: { implicitWidth: grid.implicitWidth
if (root.filteredWallpapers.length === 0) { implicitHeight: grid.implicitHeight
return 300;
} else if (root.filteredWallpapers.length < grid.columns) {
return root.filteredWallpapers.length * grid.cellWidth + 16;
} else {
return Math.min(panelWindow.width * 0.7, 900);
}
}
implicitHeight: {
if (root.filteredWallpapers.length === 0) {
return 100;
} else {
return Math.min(panelWindow.height * 0.6, Math.min(calculatedRows, 3) * grid.cellHeight + 16);
}
}
Behavior on implicitWidth {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
Behavior on implicitHeight {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
GridView { GridView {
id: grid id: grid
@@ -185,8 +178,8 @@ Item {
readonly property int rows: Math.max(1, Math.ceil(count / columns)) readonly property int rows: Math.max(1, Math.ceil(count / columns))
anchors.fill: parent anchors.fill: parent
cellWidth: root.thumbnailWidth cellWidth: width / root.columns
cellHeight: root.thumbnailHeight cellHeight: cellWidth / root.previewAspectRatio
clip: true clip: true
interactive: true interactive: true
keyNavigationWraps: true keyNavigationWraps: true
@@ -202,9 +195,7 @@ Item {
model: ScriptModel { model: ScriptModel {
values: { values: {
return root.filteredWallpapers.filter(w => ( return root.filteredWallpapers.filter(w => (w.toLowerCase().includes(root.filterQuery.toLowerCase())));
w.toLowerCase().includes(root.filterQuery.toLowerCase())
));
} }
} }
onModelChanged: currentIndex = 0 onModelChanged: currentIndex = 0
@@ -233,61 +224,49 @@ Item {
height: grid.cellHeight height: grid.cellHeight
property bool isHovered: false property bool isHovered: false
Rectangle { Image {
anchors.fill: parent id: thumbnailImage
radius: Appearance.rounding.windowRounding anchors {
color: Appearance.colors.colLayer1 fill: parent
border.width: (index === grid.currentIndex || parent.isHovered) ? 3 : 0 margins: 8
border.color: Appearance.colors.colSecondary }
} source: {
const resolvedUrl = Qt.resolvedUrl(modelData);
const md5Hash = Qt.md5(resolvedUrl);
const cacheSize = "normal";
const thumbnailPath = `${Directories.genericCache}/thumbnails/${cacheSize}/${md5Hash}.png`;
return thumbnailPath;
}
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: false
smooth: true
mipmap: false
Rectangle { sourceSize.width: Math.min(128, grid.cellWidth - 16)
anchors.fill: parent sourceSize.height: Math.min(96, grid.cellHeight - 16)
anchors.margins: 8
color: Appearance.colors.colLayer2
radius: Appearance.rounding.small
Image { opacity: status === Image.Ready ? 1 : 0
id: thumbnailImage Behavior on opacity {
anchors.fill: parent animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
source: { }
const resolvedUrl = Qt.resolvedUrl(modelData);
const md5Hash = Qt.md5(resolvedUrl);
const cacheSize = "normal";
const thumbnailPath = `${Directories.genericCache}/thumbnails/${cacheSize}/${md5Hash}.png`;
return thumbnailPath;
}
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: false
smooth: true
mipmap: false
sourceSize.width: Math.min(128, grid.cellWidth - 16) layer.enabled: true
sourceSize.height: Math.min(96, grid.cellHeight - 16) layer.effect: OpacityMask {
maskSource: Rectangle {
opacity: status === Image.Ready ? 1 : 0 width: thumbnailImage.width
Behavior on opacity { height: thumbnailImage.height
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: thumbnailImage.width
height: thumbnailImage.height
radius: Appearance.rounding.small
}
}
Rectangle {
anchors.fill: parent
color: "transparent"
border.width: 1
border.color: Appearance.colors.colOutlineVariant
radius: Appearance.rounding.small radius: Appearance.rounding.small
} }
} }
Rectangle {
anchors.fill: parent
color: "transparent"
radius: Appearance.rounding.small
border.width: (index === grid.currentIndex || parent.isHovered) ? 2 : 1
border.color: (index === grid.currentIndex || parent.isHovered) ? Appearance.colors.colSecondary : Appearance.colors.colOutlineVariant
}
} }
MouseArea { MouseArea {
@@ -313,35 +292,6 @@ Item {
} }
} }
} }
add: Transition {
from: "*"
to: "*"
ParallelAnimation {
PropertyAnimation {
property: "x"
from: grid.contentX + (grid.width / 2) - width / 2
}
PropertyAnimation {
property: "y"
from: grid.contentY + (grid.height / 2) - height / 2
}
NumberAnimation {
property: "scale"
from: 0.0
to: 1.0
duration: Appearance.animationCurves.expressiveDefaultSpatialDuration
easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial
}
NumberAnimation {
property: "opacity"
from: 0.0
to: 1.0
duration: Appearance.animationCurves.expressiveDefaultSpatialDuration
easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial
}
}
}
} }
Label { Label {