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 }