diff --git a/Config/Config.qml b/Config/Config.qml index c694c28..c02f483 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -242,6 +242,7 @@ Singleton { recolorLogo: lock.recolorLogo, enableFprint: lock.enableFprint, showNotifContent: lock.showNotifContent, + showNotifIcon: lock.showNotifIcon, maxFprintTries: lock.maxFprintTries, blurAmount: lock.blurAmount, sizes: { diff --git a/Config/LockConf.qml b/Config/LockConf.qml index bf83565..87a4f4e 100644 --- a/Config/LockConf.qml +++ b/Config/LockConf.qml @@ -6,6 +6,7 @@ JsonObject { property int maxFprintTries: 3 property bool recolorLogo: false property bool showNotifContent: false + property bool showNotifIcon: true property Sizes sizes: Sizes { } diff --git a/Modules/Lock/NotifGroup.qml b/Modules/Lock/NotifGroup.qml index eaca951..4c0302c 100644 --- a/Modules/Lock/NotifGroup.qml +++ b/Modules/Lock/NotifGroup.qml @@ -58,6 +58,7 @@ CustomRect { fillMode: Image.PreserveAspectCrop height: Config.notifs.sizes.image source: Qt.resolvedUrl(root.image) + visible: Config.lock.showNotifIcon width: Config.notifs.sizes.image } } diff --git a/Modules/Settings/Categories/Background.qml b/Modules/Settings/Categories/Background.qml index 4f7390e..233c31f 100644 --- a/Modules/Settings/Categories/Background.qml +++ b/Modules/Settings/Categories/Background.qml @@ -36,7 +36,6 @@ SettingsPage { } WallpaperCropper { - screen: root.screen } } diff --git a/Modules/Settings/Categories/Lockscreen.qml b/Modules/Settings/Categories/Lockscreen.qml index 9c63787..50c93db 100644 --- a/Modules/Settings/Categories/Lockscreen.qml +++ b/Modules/Settings/Categories/Lockscreen.qml @@ -50,6 +50,15 @@ SettingsPage { Separator { } + SettingSwitch { + name: "Show notification icon" + object: Config.lock + setting: "showNotifIcon" + } + + Separator { + } + SettingSpinBox { min: 0 name: "Blur amount" diff --git a/Modules/Settings/Controls/WallpaperCropper.qml b/Modules/Settings/Controls/WallpaperCropper.qml index 4fba8dd..bd3ff93 100644 --- a/Modules/Settings/Controls/WallpaperCropper.qml +++ b/Modules/Settings/Controls/WallpaperCropper.qml @@ -4,171 +4,255 @@ import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Hyprland +import ZShell.Internal import qs.Config import qs.Components import qs.Helpers -RowLayout { - id: root +Item { + id: wrapper - required property ShellScreen screen + property bool changesMade: false + + signal requestCrop Layout.fillWidth: true Layout.preferredHeight: 400 - spacing: Appearance.spacing.normal - Repeater { - model: ScriptModel { - values: [...Quickshell.screens].sort((a, b) => { - return a.x - b.x; - }) + IconButton { + anchors.margins: Appearance.padding.normal + anchors.right: parent.right + anchors.top: parent.top + icon: "check" + opacity: wrapper.changesMade ? 1 : 0 + scale: wrapper.changesMade ? 1 : 0 + z: 2 + + Behavior on opacity { + Anim { + } + } + Behavior on scale { + Anim { + } } - Item { - id: delegate + onClicked: { + wrapper.requestCrop(); + wrapper.changesMade = false; + } + } - required property ShellScreen modelData + RowLayout { + id: root - Layout.fillHeight: true - Layout.fillWidth: true + anchors.fill: parent + spacing: Appearance.spacing.normal - Image { - id: scaledImg + Repeater { + model: ScriptModel { + values: [...Quickshell.screens].sort((a, b) => { + return a.x - b.x; + }) + } - property var displayData - readonly property real imageRatio: scaledImg.sourceSize.width / scaledImg.sourceSize.height - property real monitorScale: 1.0 - readonly property real scaleDownX: scaledImg.width / scaledImg.sourceSize.width - readonly property real scaleDownY: scaledImg.height / scaledImg.sourceSize.height - readonly property real scaleX: (scaledImg.sourceSize.width * monitorScale) / scaledImg.width - readonly property real scaleY: (scaledImg.sourceSize.height * monitorScale) / scaledImg.height + Item { + id: delegate - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - height: width / imageRatio - source: Wallpapers.current + required property ShellScreen modelData - onPaintedWidthChanged: { - if (paintedWidth > 0) { - scaledImg.displayData = Wallpapers.getCrop(delegate.modelData.name); - cropRect.zoom = Wallpapers.getCrop(delegate.modelData.name).zoom; - cropRect.restoreFromData(); - } + function applyCrop(): void { + const croprect = cropRect.mapToItem(scaledImg, 0, 0, cropRect.width, cropRect.height); + const upscaledRect = Qt.rect((croprect.x - cropRect.imageX) / scaledImg.paintedWidth, (croprect.y - cropRect.imageY) / scaledImg.paintedHeight, croprect.width / scaledImg.paintedWidth, croprect.height / scaledImg.paintedHeight); + Wallpapers.setCrop(delegate.modelData.name, upscaledRect, croprect, cropRect.zoom); } - CustomText { - id: monitorId + function zoomClipRect(zoom: real): void { + let oldCenterX = cropRect.x + cropRect.width * 0.5; + let oldCenterY = cropRect.y + cropRect.height * 0.5; - anchors.centerIn: parent - color: Qt.alpha(DynamicColors.palette.m3surface, 0.85) - font.pointSize: Appearance.font.size.large * 4 - style: Text.Outline - styleColor: DynamicColors.palette.m3onSurface - text: delegate.modelData.name + cropRect.zoom = zoom; + + cropRect.x = oldCenterX - cropRect.width * 0.5; + cropRect.y = oldCenterY - cropRect.height * 0.5; + + cropRect.clampToBounds(); } - CustomRect { - id: cropRect + Layout.fillHeight: true + Layout.fillWidth: true - property real aspectRatio: delegate.modelData.width / delegate.modelData.height - readonly property real baseHeight: baseWidth / aspectRatio - readonly property real baseWidth: { - let fittedHeight = scaledImg.height; - let fittedWidth = fittedHeight * aspectRatio; - - if (fittedWidth > scaledImg.width) { - fittedWidth = scaledImg.width; - fittedHeight = fittedWidth / aspectRatio; - } - - return fittedWidth; - } - readonly property real imageX: (scaledImg.width - scaledImg.width) / 2 - readonly property real imageY: (scaledImg.height - scaledImg.height) / 2 - property real zoom: scaledImg.displayData.zoom - - function centerInImage() { - x = imageX + (scaledImg.width - width) / 2; - y = imageY + (scaledImg.height - height) / 2; + Connections { + function onRequestCrop(): void { + delegate.applyCrop(); } - function clampToBounds() { - x = Math.max(imageX, Math.min(x, imageX + scaledImg.paintedWidth - width)); + target: wrapper + } - y = Math.max(imageY, Math.min(y, imageY + scaledImg.paintedHeight - height)); + RowLayout { + id: sliderLayout + + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + implicitHeight: 30 + spacing: Appearance.spacing.large + + CustomText { + text: qsTr("Crop scale") } - function restoreFromData() { - let data = scaledImg.displayData; + CustomSlider { + id: zoomSlider - if (data && data.scaledX !== 0 || data.scaledY !== 0 || data.scaledWidth !== 0 || data.scaledHeight !== 0) { - x = data.scaledX; - y = data.scaledY; + Layout.fillWidth: true + Layout.preferredHeight: 10 + from: 1.0 + to: 5.0 + value: cropRect.zoom - clampToBounds(); - } else { - zoom = 1.0; - centerInImage(); + onMoved: { + delegate.zoomClipRect(value); + wrapper.changesMade = true; } } - - border.color: "lime" - border.width: 2 - height: baseHeight / zoom - width: baseWidth / zoom - - onHeightChanged: clampToBounds() - onWidthChanged: clampToBounds() } - MouseArea { - id: mouse + CachingImage { + id: scaledImg - function updateCrop(mouseX, mouseY) { - let nx = mouseX - cropRect.width * 0.5; - let ny = mouseY - cropRect.height * 0.5; + property var displayData + property real monitorScale: 1.0 - nx = Math.max(cropRect.imageX, Math.min(nx, cropRect.imageX + scaledImg.width - cropRect.width)); + anchors.bottom: sliderLayout.top + anchors.bottomMargin: Appearance.spacing.normal + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + asynchronous: true + fillMode: Image.PreserveAspectFit + // retainWhileLoading: true + source: Wallpapers.current + sourceSize.height: parent.height + sourceSize.width: parent.width - ny = Math.max(cropRect.imageY, Math.min(ny, cropRect.imageY + scaledImg.height - cropRect.height)); + onPaintedWidthChanged: { + if (paintedWidth > 0) { + scaledImg.displayData = Wallpapers.getCrop(delegate.modelData.name); + cropRect.zoom = Wallpapers.getCrop(delegate.modelData.name).zoom; + cropRect.restoreFromData(); + } + } + onSourceChanged: cropRect.clampToBounds() + onStatusChanged: if (scaledImg.status == Image.Ready) + cropRect.clampToBounds() - cropRect.x = nx; - cropRect.y = ny; + CustomText { + id: monitorId + + anchors.centerIn: parent + color: Qt.alpha(DynamicColors.palette.m3surface, 0.85) + font.pointSize: Appearance.font.size.large * 4 + style: Text.Outline + styleColor: DynamicColors.palette.m3onSurface + text: delegate.modelData.name } - anchors.fill: parent - hoverEnabled: true - preventStealing: true + CustomRect { + id: cropRect - onPositionChanged: mouse => { - if (pressed) + property real aspectRatio: delegate.modelData.width / delegate.modelData.height + readonly property real baseHeight: baseWidth / aspectRatio + readonly property real baseWidth: { + let fittedHeight = scaledImg.paintedHeight; + let fittedWidth = fittedHeight * aspectRatio; + + if (fittedWidth > scaledImg.paintedWidth) { + fittedWidth = scaledImg.paintedWidth; + fittedHeight = fittedWidth / aspectRatio; + } + + return fittedWidth; + } + readonly property real imageX: (scaledImg.width - scaledImg.paintedWidth) / 2 + readonly property real imageY: (scaledImg.height - scaledImg.paintedHeight) / 2 + property real imgAspectRatio: scaledImg.paintedWidth / scaledImg.paintedHeight + property real zoom: scaledImg.displayData.zoom + + function centerInImage() { + x = imageX + (scaledImg.paintedWidth - width) / 2; + y = imageY + (scaledImg.paintedHeight - height) / 2; + } + + function clampToBounds() { + x = Math.max(imageX, Math.min(x, imageX + scaledImg.paintedWidth - width)); + + y = Math.max(imageY, Math.min(y, imageY + scaledImg.paintedHeight - height)); + } + + function restoreFromData() { + let data = scaledImg.displayData; + + if (data && data.scaledX !== 0 || data.scaledY !== 0 || data.scaledWidth !== 0 || data.scaledHeight !== 0) { + x = data.scaledX; + y = data.scaledY; + + clampToBounds(); + } else { + zoom = 1.0; + centerInImage(); + } + } + + border.color: DynamicColors.palette.m3primary + border.width: 2 + height: baseHeight / zoom + opacity: 1 + width: baseWidth / zoom + + Behavior on opacity { + Anim { + } + } + + Component.onCompleted: clampToBounds() + onHeightChanged: clampToBounds() + onWidthChanged: clampToBounds() + } + + MouseArea { + id: mouse + + function updateCrop(mouseX, mouseY) { + let nx = mouseX - cropRect.width * 0.5; + let ny = mouseY - cropRect.height * 0.5; + + nx = Math.max(cropRect.imageX, Math.min(nx, cropRect.imageX + scaledImg.paintedWidth - cropRect.width)); + + ny = Math.max(cropRect.imageY, Math.min(ny, cropRect.imageY + scaledImg.paintedHeight - cropRect.height)); + + cropRect.x = nx; + cropRect.y = ny; + } + + anchors.fill: parent + hoverEnabled: true + preventStealing: true + + onPositionChanged: mouse => { + if (pressed) { + updateCrop(mouse.x, mouse.y); + wrapper.changesMade = true; + } + } + onPressed: mouse => { updateCrop(mouse.x, mouse.y); - } - onPressed: mouse => { - updateCrop(mouse.x, mouse.y); - } - onReleased: { - const croprect = cropRect.mapToItem(scaledImg, 0, 0, cropRect.width, cropRect.height); - const upscaledRect = Qt.rect(croprect.x / scaledImg.width, croprect.y / scaledImg.height, croprect.width / scaledImg.width, croprect.height / scaledImg.height); - Wallpapers.setCrop(delegate.modelData.name, upscaledRect, croprect, cropRect.zoom); - } - onWheel: wheel => { - let oldCenterX = cropRect.x + cropRect.width * 0.5; - let oldCenterY = cropRect.y + cropRect.height * 0.5; - - if (wheel.angleDelta.y > 0) - cropRect.zoom *= 1.1; - else - cropRect.zoom /= 1.1; - - cropRect.zoom = Math.max(1.0, Math.min(cropRect.zoom, 5.0)); - console.log(cropRect.zoom); - - cropRect.x = oldCenterX - cropRect.width * 0.5; - cropRect.y = oldCenterY - cropRect.height * 0.5; - - cropRect.clampToBounds(); + wrapper.changesMade = true; + } + onReleased: { + wrapper.changesMade = true; + } } } } diff --git a/scripts/SettingsIndex.mjs b/scripts/SettingsIndex.mjs index 8e6303a..12c74e1 100644 --- a/scripts/SettingsIndex.mjs +++ b/scripts/SettingsIndex.mjs @@ -311,6 +311,13 @@ export const settingsIndex = [ section: "Lockscreen", keywords: ["notification", "hide", "privacy"], }, + { + name: "Show notification icon", + category: "lockscreen", + categoryName: "Lockscreen", + section: "Lockscreen", + keywords: ["notification", "hide", "icon"], + }, { name: "Blur amount", category: "lockscreen",