MauiKit Terminal

TerminalInputArea.qml
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored-by: Filippo Scognamiglio <flscogna@gmail.com>
17 */
18import QtQuick 2.4
19
20Item
21{
22 property bool touchAreaPressed: false
23 property real swipeDelta: units.gu(1)
24
25 // Mouse signals
26 signal mouseMoveDetected(int x, int y, int button, int buttons, int modifiers);
27 signal doubleClickDetected(int x, int y, int button, int buttons, int modifiers);
28 signal mousePressDetected(int x, int y, int button, int buttons, int modifiers);
29 signal mouseReleaseDetected(int x, int y, int button, int buttons, int modifiers);
30 signal mouseWheelDetected(int x, int y, int buttons, int modifiers, point angleDelta);
31
32 // Touch signals
33 signal touchPressAndHold(int x, int y);
34 signal touchClick(int x, int y);
35 signal touchPress(int x, int y);
36 signal touchRelease(int x, int y);
37
38 signal swipeYDetected(int steps);
39 signal swipeXDetected(int steps);
40 signal twoFingerSwipeYDetected(int steps);
41 signal twoFingerSwipeXDetected(int steps);
42
43 // Semantic signals
44 signal alternateAction(int x, int y);
45
46 function avg(p1, p2) {
47 return Qt.point((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
48 }
49
50 function distance(p1, p2) {
51 return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
52 }
53
54 function absFloor(val) {
55 return val > 0 ? Math.floor(val) : Math.ceil(val);
56 }
57
58 MultiPointTouchArea {
59 property bool __moved: false
60 property bool __multiTouch: false // Decide whether this is a single or multi touch gesture before handling it. Otherwise, we run into problems while switching between the two modes.
61 property point __pressPosition: Qt.point(0, 0);
62 property real __prevDragStepsY: 0
63 property real __prevDragStepsX: 0
64
65 // This enum represent the status of the dragging.
66 // It is used to avoid simultaneously dragging along both axies
67 // as it's very error prone.
68
69 readonly property int noDragging: 0
70 readonly property int yDragging: 1
71 readonly property int xDragging: 2
72 property real __dragging: noDragging
73
74 id: singleTouchTouchArea
75
76 anchors.fill: parent
77 z: parent.z + 0.01
78
79 // TODO Interval should be the same used by all system applications.
80 Timer {
81 id: pressAndHoldTimer
82 running: false
83 onTriggered: {
84 if (!parent.__moved)
85 touchPressAndHold(singleTouchTouchArea.__pressPosition.x,
86 singleTouchTouchArea.__pressPosition.y);
87 }
88 }
89
90 Timer {
91 id: multiTouchTimer
92 running: false
93 interval: 200
94 }
95
96 maximumTouchPoints: 1
97 onPressed: {
98 touchAreaPressed = true;
99 __moved = false;
100 __multiTouch = false;
101 __prevDragStepsY = 0.0;
102 __prevDragStepsX = 0.0;
103 __dragging = noDragging;
104 __pressPosition = Qt.point(touchPoints[0].x, touchPoints[0].y);
105 pressAndHoldTimer.start();
106 multiTouchTimer.start(); // Detect if this is going to be a multi touch swipe while the timer is running
107
108 touchPress(touchPoints[0].x, touchPoints[0].y);
109 }
110 onUpdated: {
111 if (__multiTouch || multiTouchTimer.running) // Do not handle multi touch events here and detect multi touch swipes while the timer is running
112 return;
113
114 var dragValueY = touchPoints[0].y - __pressPosition.y;
115 var dragValueX = touchPoints[0].x - __pressPosition.x;
116 var dragStepsY = dragValueY / swipeDelta;
117 var dragStepsX = dragValueX / swipeDelta;
118
119 var dragStepsFloorY = absFloor(dragStepsY);
120 var dragStepsFloorX = absFloor(dragStepsX);
121
122 if (!__moved && distance(touchPoints[0], __pressPosition) > swipeDelta) {
123 __moved = true;
124 __dragging = (Math.abs(dragValueY) >= Math.abs(dragValueX)) ? yDragging : xDragging;
125 } else if (!__moved) {
126 return;
127 }
128
129 if (__dragging === yDragging && dragStepsFloorY !== __prevDragStepsY) {
130 swipeYDetected(dragStepsFloorY - __prevDragStepsY);
131 } else if (__dragging === xDragging && dragStepsFloorX !== __prevDragStepsX) {
132 swipeXDetected(dragStepsFloorX - __prevDragStepsX);
133 }
134
135 __prevDragStepsY = dragStepsFloorY;
136 __prevDragStepsX = dragStepsFloorX;
137 }
138 onReleased: {
139 var timerRunning = pressAndHoldTimer.running;
140 pressAndHoldTimer.stop();
141 touchAreaPressed = false;
142
143 if (!__moved && timerRunning) {
144 touchClick(touchPoints[0].x, touchPoints[0].y);
145 }
146
147 touchRelease(touchPoints[0].x, touchPoints[0].y);
148 }
149
150 MultiPointTouchArea {
151 property point __pressPosition: Qt.point(0, 0);
152 property real __prevDragSteps: 0
153
154 id: doubleTouchTouchArea
155 anchors.fill: parent
156 z: parent.z + 0.001
157
158 maximumTouchPoints: 2
159 minimumTouchPoints: 2
160 onPressed: {
161 if (!multiTouchTimer.running) // Already recognized as single touch swipe
162 return;
163
164 __pressPosition = avg(touchPoints[0], touchPoints[1]);
165 __prevDragSteps = 0;
166
167 singleTouchTouchArea.__moved = true;
168 singleTouchTouchArea.__multiTouch = true;
169 }
170 onUpdated: {
171 // WORKAROUND: filter bad events that somehow get here during release.
172 if (touchPoints.length !== 2)
173 return;
174
175 if (!singleTouchTouchArea.__multiTouch)
176 return;
177
178 var touchPoint = avg(touchPoints[0], touchPoints[1]);
179 var dragValue = touchPoint.y - __pressPosition.y;
180 var dragSteps = dragValue / swipeDelta;
181
182 var dragStepsFloorY = absFloor(dragSteps);
183
184 if (dragStepsFloorY !== __prevDragSteps) {
185 twoFingerSwipeYDetected(dragStepsFloorY - __prevDragSteps);
186 }
187
188 __prevDragSteps = dragStepsFloorY;
189 }
190
191 mouseEnabled: false
192 }
193
194 mouseEnabled: false
195 }
196
197 MouseArea {
198 id: mouseArea
199 anchors.fill: parent
200 enabled: !parent.touchAreaPressed
201 acceptedButtons: Qt.AllButtons
202 cursorShape: Qt.IBeamCursor
203
204 z: parent.z
205
206 onDoubleClicked: (mouse) => {
207 doubleClickDetected(mouse.x, mouse.y, mouse.button, mouse.buttons, mouse.modifiers);
208 }
209 onPositionChanged: (mouse) => {
210 mouseMoveDetected(mouse.x, mouse.y, mouse.button, mouse.buttons, mouse.modifiers);
211 }
212 onPressed: (mouse) => {
213 // Do not handle the right click if the terminal needs them.
214 if (mouse.button === Qt.RightButton ) {
215 alternateAction(mouse.x, mouse.y);
216 } else {
217 mousePressDetected(mouse.x, mouse.y, mouse.button, mouse.buttons, mouse.modifiers);
218 }
219 }
220 onReleased: (mouse) => {
221 mouseReleaseDetected(mouse.x, mouse.y, mouse.button, mouse.buttons, mouse.modifiers);
222 }
223 onWheel: (wheel) => {
224 mouseWheelDetected(wheel.x, wheel.y, wheel.buttons, wheel.modifiers, wheel.angleDelta);
225 }
226 }
227}
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Aug 30 2024 11:51:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.