Warning, /libraries/kquickimageeditor/src/controls/SelectionTool.qml is written in an unsupported language. File is not indexed.

0001 /* SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0002  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0003  */
0004 
0005 import QtQuick 2.15
0006 import QtQml 2.15
0007 
0008 Item {
0009     id: root
0010     // make this readonly so it can be accessed without risking external modification
0011     readonly property SelectionHandle pressedHandle: _private.pressedHandle
0012     readonly property alias selectionArea: selectionArea
0013     property alias selectionX: selectionArea.x
0014     property alias selectionY: selectionArea.y
0015     property alias selectionWidth: selectionArea.width
0016     property alias selectionHeight: selectionArea.height
0017 
0018     QtObject {
0019         id: _private
0020         property SelectionHandle pressedHandle: null
0021     }
0022 
0023     MouseArea {
0024         id: selectionArea
0025         x: 0
0026         y: 0
0027         z: 1
0028         width: parent.width
0029         height: parent.height
0030         LayoutMirroring.enabled: false
0031         anchors.left: if (_private.pressedHandle) {
0032             if (_private.pressedHandle.backwardDiagonal) {
0033                 handleTopLeft.horizontalCenter
0034             } else if (_private.pressedHandle.forwardDiagonal) {
0035                 handleBottomLeft.horizontalCenter
0036             } else if (_private.pressedHandle.horizontalOnly) {
0037                 handleLeft.horizontalCenter
0038             }
0039         }
0040         anchors.right: if (_private.pressedHandle) {
0041             if (_private.pressedHandle.backwardDiagonal) {
0042                 handleBottomRight.horizontalCenter
0043             } else if (_private.pressedHandle.forwardDiagonal) {
0044                 handleTopRight.horizontalCenter
0045             } else if (_private.pressedHandle.horizontalOnly) {
0046                 handleRight.horizontalCenter
0047             }
0048         }
0049         anchors.top: if (_private.pressedHandle) {
0050             if (_private.pressedHandle.backwardDiagonal) {
0051                 handleTopLeft.verticalCenter
0052             } else if (_private.pressedHandle.forwardDiagonal) {
0053                 handleTopRight.verticalCenter
0054             } else if (_private.pressedHandle.verticalOnly) {
0055                 handleTop.verticalCenter
0056             }
0057         }
0058         anchors.bottom: if (_private.pressedHandle) {
0059             if (_private.pressedHandle.backwardDiagonal) {
0060                 handleBottomRight.verticalCenter
0061             } else if (_private.pressedHandle.forwardDiagonal) {
0062                 handleBottomLeft.verticalCenter
0063             } else if (_private.pressedHandle.verticalOnly) {
0064                 handleBottom.verticalCenter
0065             }
0066         }
0067         enabled: drag.target
0068         cursorShape: if (_private.pressedHandle || (pressed && enabled)) {
0069             Qt.ClosedHandCursor
0070         } else if (enabled) {
0071             Qt.OpenHandCursor
0072         } else {
0073             Qt.ArrowCursor
0074         }
0075         drag {
0076             axis: Drag.XAndYAxis
0077             target: (selectionArea.width === root.width && selectionArea.height === root.height) || _private.pressedHandle ? null : selectionArea
0078             minimumX: 0
0079             maximumX: root.width - selectionArea.width
0080             minimumY: 0
0081             maximumY: root.height - selectionArea.height
0082             threshold: 0
0083         }
0084     }
0085 
0086     SelectionHandle {
0087         id: handleTopLeft
0088         target: selectionArea
0089         position: SelectionHandle.TopLeft
0090         lockX: _private.pressedHandle && _private.pressedHandle.backwardDiagonal
0091         lockY: lockX
0092         drag.maximumX: handleBottomRight.x - implicitWidth / 2
0093         drag.maximumY: handleBottomRight.y - implicitHeight / 2
0094         Binding {
0095             target: _private; property: "pressedHandle"
0096             value: handleTopLeft; when: handleTopLeft.pressed
0097             restoreMode: Binding.RestoreBindingOrValue
0098         }
0099     }
0100     SelectionHandle {
0101         id: handleTop
0102         visible: selectionArea.width >= implicitWidth
0103         target: selectionArea
0104         position: SelectionHandle.Top
0105         lockY: _private.pressedHandle && _private.pressedHandle.verticalOnly
0106         drag.maximumY: handleBottom.y - implicitHeight / 2
0107         Binding {
0108             target: _private; property: "pressedHandle"
0109             value: handleTop; when: handleTop.pressed
0110             restoreMode: Binding.RestoreBindingOrValue
0111         }
0112     }
0113     SelectionHandle {
0114         id: handleTopRight
0115         target: selectionArea
0116         position: SelectionHandle.TopRight
0117         lockX: _private.pressedHandle && _private.pressedHandle.forwardDiagonal
0118         lockY: lockX
0119         drag.minimumX: handleBottomLeft.x + implicitWidth / 2
0120         drag.maximumY: handleBottomLeft.y - implicitHeight / 2
0121         Binding {
0122             target: _private; property: "pressedHandle"
0123             value: handleTopRight; when: handleTopRight.pressed
0124             restoreMode: Binding.RestoreBindingOrValue
0125         }
0126     }
0127     SelectionHandle {
0128         id: handleLeft
0129         visible: selectionArea.height >= implicitHeight
0130         target: selectionArea
0131         position: SelectionHandle.Left
0132         lockX: _private.pressedHandle && _private.pressedHandle.horizontalOnly
0133         drag.maximumX: handleRight.x - implicitWidth / 2
0134         Binding {
0135             target: _private; property: "pressedHandle"
0136             value: handleLeft; when: handleLeft.pressed
0137             restoreMode: Binding.RestoreBindingOrValue
0138         }
0139     }
0140     SelectionHandle {
0141         id: handleRight
0142         visible: selectionArea.height >= implicitHeight
0143         target: selectionArea
0144         position: SelectionHandle.Right
0145         lockX: _private.pressedHandle && _private.pressedHandle.horizontalOnly
0146         drag.minimumX: handleLeft.x + implicitWidth / 2
0147         Binding {
0148             target: _private; property: "pressedHandle"
0149             value: handleRight; when: handleRight.pressed
0150             restoreMode: Binding.RestoreBindingOrValue
0151         }
0152     }
0153     SelectionHandle {
0154         id: handleBottomLeft
0155         target: selectionArea
0156         position: SelectionHandle.BottomLeft
0157         lockX: _private.pressedHandle && _private.pressedHandle.forwardDiagonal
0158         lockY: lockX
0159         drag.maximumX: handleTopRight.x - implicitWidth / 2
0160         drag.minimumY: handleTopRight.y + implicitHeight / 2
0161         Binding {
0162             target: _private; property: "pressedHandle"
0163             value: handleBottomLeft; when: handleBottomLeft.pressed
0164             restoreMode: Binding.RestoreBindingOrValue
0165         }
0166     }
0167     SelectionHandle {
0168         id: handleBottom
0169         visible: selectionArea.width >= implicitWidth
0170         target: selectionArea
0171         position: SelectionHandle.Bottom
0172         lockY: _private.pressedHandle && _private.pressedHandle.verticalOnly
0173         drag.minimumY: handleTop.y + implicitHeight / 2
0174         Binding {
0175             target: _private; property: "pressedHandle"
0176             value: handleBottom; when: handleBottom.pressed
0177             restoreMode: Binding.RestoreBindingOrValue
0178         }
0179     }
0180     SelectionHandle {
0181         id: handleBottomRight
0182         target: selectionArea
0183         position: SelectionHandle.BottomRight
0184         lockX: _private.pressedHandle && _private.pressedHandle.backwardDiagonal
0185         lockY: lockX
0186         drag.minimumX: handleTopLeft.x + implicitWidth / 2
0187         drag.minimumY: handleTopLeft.y + implicitHeight / 2
0188         Binding {
0189             target: _private; property: "pressedHandle"
0190             value: handleBottomRight; when: handleBottomRight.pressed
0191             restoreMode: Binding.RestoreBindingOrValue
0192         }
0193     }
0194     // TODO: maybe scale proportions instead of just limiting size
0195     onWidthChanged: if (selectionArea.x + selectionArea.width > root.width) {
0196         selectionArea.width = Math.max(root.width - selectionArea.x, handleTopLeft.implicitWidth/2)
0197         if (selectionArea.x > root.width) {
0198             selectionArea.x = Math.max(root.width - selectionArea.width, 0)
0199         }
0200     }
0201     onHeightChanged: if (selectionArea.y + selectionArea.height > root.height) {
0202         selectionArea.height = Math.max(root.height - selectionArea.y, handleTopLeft.implicitHeight/2)
0203         if (selectionArea.y > root.height) {
0204             selectionArea.y = Math.max(root.height - selectionArea.height, 0)
0205         }
0206     }
0207 }