diff --git a/ui/shared/CropCornerRectangle.qml b/ui/shared/CropCornerRectangle.qml index ed7165dda7..3a2b44d235 100644 --- a/ui/shared/CropCornerRectangle.qml +++ b/ui/shared/CropCornerRectangle.qml @@ -2,6 +2,9 @@ import QtQuick 2.13 import "../imports" Rectangle { + signal released() + signal pressed() + id: root width: 25 height: 25 @@ -19,5 +22,7 @@ Rectangle { anchors.fill: parent drag.target: parent cursorShape: Qt.PointingHandCursor + onReleased: root.released() + onPressed: root.pressed() } } diff --git a/ui/shared/ImageCropper.qml b/ui/shared/ImageCropper.qml index 95f1713b6d..57812d50ee 100644 --- a/ui/shared/ImageCropper.qml +++ b/ui/shared/ImageCropper.qml @@ -5,6 +5,17 @@ import "../imports" Item { property var image property alias selectorRectangle: selectorRectangle + property string ratio: "" + property var splitRatio: !!ratio ? ratio.split(":") : null + property int widthRatio: !!ratio ? parseInt(splitRatio[0]) : -1 + property int heightRatio: !!ratio ? parseInt(splitRatio[1]) : -1 + property bool settingCorners: false + property int draggedCorner: 0 + + readonly property int topLeft: 0 + readonly property int topRight: 1 + readonly property int bottomLeft: 2 + readonly property int bottomRight: 3 width: image.width height: image.height @@ -18,25 +29,65 @@ Item { border.color: Style.current.orange color: Style.current.transparent - function initialSetup() { - topLeftCorner.x = 0 - topLeftCorner.y = 0 - topRightCorner.x = image.width - topRightCorner.width - topRightCorner.y = 0 - bottomLeftCorner.x = 0 - bottomLeftCorner.y = image.height - topRightCorner.height - bottomRightCorner.x = image.width - topRightCorner.width - bottomRightCorner.y = image.height - topRightCorner.height - - selectorRectangle.width = image.width - selectorRectangle.height = image.height + function fitRatio(makeBigger) { + if (!!ratio) { + if ((makeBigger && selectorRectangle.width < selectorRectangle.height) || (!makeBigger && selectorRectangle.width > selectorRectangle.height)) { + selectorRectangle.width = (selectorRectangle.height/heightRatio) * widthRatio + } else { + selectorRectangle.height = (selectorRectangle.width/widthRatio) * heightRatio + } + } } + function initialSetup() { + selectorRectangle.width = image.width + selectorRectangle.height = image.height + + fitRatio() + topLeftCorner.x = 0 + topLeftCorner.y = 0 + topRightCorner.x = selectorRectangle.width - topRightCorner.width + topRightCorner.y = 0 + bottomLeftCorner.x = 0 + bottomLeftCorner.y = selectorRectangle.height - topRightCorner.height + bottomRightCorner.x = selectorRectangle.width - topRightCorner.width + bottomRightCorner.y = selectorRectangle.height - topRightCorner.height + } + + function adjustRectangleSize() { + if (!selectorRectangle.visible) { + return + } + selectorRectangle.width = bottomRightCorner.x + bottomRightCorner.width - topLeftCorner.x selectorRectangle.height = bottomRightCorner.y + bottomRightCorner.height - topLeftCorner.y selectorRectangle.x = topLeftCorner.x selectorRectangle.y = topLeftCorner.y + + if (!!ratio) { + // FIXME with a ratio that is not 1:1, the rectangle can go out of bounds + fitRatio() + + switch(draggedCorner) { + case topLeft: + selectorRectangle.x = topLeftCorner.x + selectorRectangle.y = topLeftCorner.y + break + case topRight: + selectorRectangle.x = topRightCorner.x - selectorRectangle.width + topRightCorner.width + selectorRectangle.y = topRightCorner.y + break + case bottomLeft: + selectorRectangle.x = bottomLeftCorner.x + selectorRectangle.y = bottomLeftCorner.y - selectorRectangle.height + bottomLeftCorner.height + break + case bottomRight: + selectorRectangle.x = bottomRightCorner.x - selectorRectangle.width + bottomRightCorner.width + selectorRectangle.y = bottomRightCorner.y - selectorRectangle.height + bottomRightCorner.height + break + } + } } Connections { @@ -49,11 +100,27 @@ Item { } } } + function putCorners() { + settingCorners = true + + topLeftCorner.x = selectorRectangle.x + topLeftCorner.y = selectorRectangle.y + topRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width + topRightCorner.y = selectorRectangle.y + bottomLeftCorner.x = selectorRectangle.x + bottomLeftCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height + bottomRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width + bottomRightCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height + + settingCorners = false + } + // Size calculations are only done on top-left and bottom-right, because the other two corners follow them CropCornerRectangle { id: topLeftCorner onXChanged: { + if (settingCorners) return if (x < 0) x = 0 if (x > topRightCorner.x - width) x = topRightCorner.x - width @@ -61,47 +128,81 @@ Item { selectorRectangle.adjustRectangleSize() } onYChanged: { + if (settingCorners) return if (y < 0) y = 0 if (y > bottomRightCorner.y - height) y = bottomRightCorner.y - height topRightCorner.y = y selectorRectangle.adjustRectangleSize() } + onPressed: { + draggedCorner = topLeft + } + + onReleased: { + putCorners() + } } CropCornerRectangle { id: topRightCorner onXChanged: { + if (settingCorners) return bottomRightCorner.x = x } onYChanged: { + if (settingCorners) return topLeftCorner.y = y } + onPressed: { + draggedCorner = topRight + } + onReleased: { + putCorners() + } } CropCornerRectangle { id: bottomLeftCorner onXChanged: { + if (settingCorners) return topLeftCorner.x = x } onYChanged: { + if (settingCorners) return bottomRightCorner.y = y } + onPressed: { + draggedCorner = bottomLeft + } + onReleased: { + putCorners() + } } CropCornerRectangle { id: bottomRightCorner onXChanged: { + if (settingCorners) return if (x < topLeftCorner.x + topLeftCorner.width) x = topLeftCorner.x + topLeftCorner.width if (x > image.width - width) x = image.width - width topRightCorner.x = x + selectorRectangle.adjustRectangleSize() } onYChanged: { + if (settingCorners) return if (y < topRightCorner.y + topRightCorner.height) y = topRightCorner.y + topRightCorner.height if (y > image.height - height) y = image.height - height bottomLeftCorner.y = y + selectorRectangle.adjustRectangleSize() } + onPressed: { + draggedCorner = bottomRight + } + onReleased: { + putCorners() + } } }