From 59083532cca0bd07857d68bf5df1ef35109ba972 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 23 Dec 2023 16:27:07 -0500 Subject: [PATCH] Make the image overlay behave better Previously, the image would not try to stay centered; furthermore, on mobile devices, it was impossible to zoom images without dropping them at a slightly off rotation. This bothered me enough that I've clamped images to the center of the screen (as long as they aren't zoomed larger than the screen) and snapped rotations to 45-degree increments (with a nice animation to boot). --- resources/qml/dialogs/ImageOverlay.qml | 44 +++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/resources/qml/dialogs/ImageOverlay.qml b/resources/qml/dialogs/ImageOverlay.qml index b914829e8..ac7f807bf 100644 --- a/resources/qml/dialogs/ImageOverlay.qml +++ b/resources/qml/dialogs/ImageOverlay.qml @@ -50,6 +50,8 @@ Window { property int imgSrcWidth: (imageOverlay.originalWidth && imageOverlay.originalWidth > 100) ? imageOverlay.originalWidth : Screen.width property int imgSrcHeight: imageOverlay.proportionalHeight ? imgSrcWidth * imageOverlay.proportionalHeight : Screen.height + readonly property int physicalWidth: width * scale + readonly property int physicalHeight: height * scale height: Math.min(parent.height || Screen.height, imgSrcHeight) width: Math.min(parent.width || Screen.width, imgSrcWidth) @@ -57,6 +59,22 @@ Window { x: (parent.width - width) / 2 y: (parent.height - height) / 2 + onXChanged: { + if (physicalWidth < Screen.width) + x = (parent.width - width) / 2; + } + onYChanged: { + if (physicalHeight < Screen.height) + y = (parent.height - height) / 2; + } + + Behavior on rotation { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + Image { id: img @@ -87,13 +105,30 @@ Window { } Item { - anchors.fill: parent + id: handlerContainer + + function snapImageRotation() + { + // snap to 15-degree angles + let rotationOffset = imgContainer.rotation % 15; + if (rotationOffset != 0) + { + if (rotationOffset < 7.5) + imgContainer.rotation -= rotationOffset; + else + imgContainer.rotation += rotationOffset; + } + } + + anchors.fill: parent PinchHandler { target: imgContainer maximumScale: 10 minimumScale: 0.1 + + onGrabChanged: handlerContainer.snapImageRotation() } WheelHandler { @@ -103,10 +138,17 @@ Window { // and we don't yet distinguish mice and trackpads on Wayland either acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad target: imgContainer + + // TODO: in theory this should work, but in practice it's not triggering + onGrabChanged: handlerContainer.snapImageRotation() } DragHandler { target: imgContainer + xAxis.enabled: imgContainer.physicalWidth > Screen.width + yAxis.enabled: imgContainer.physicalHeight > Screen.height + + onGrabChanged: handlerContainer.snapImageRotation() } HoverHandler {