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 }