Lomiri
TabletSideStageTouchGesture.qml
1 /*
2  * Copyright (C) 2016 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 as published by
6  * the Free Software Foundation; version 3.
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 
17 import QtQuick 2.12
18 import Lomiri.Gestures 0.1
19 
20 TouchGestureArea {
21  id: root
22  minimumTouchPoints: 3
23  maximumTouchPoints: 3
24 
25  property bool enableDrag: true
26  property Component dragComponent
27  property var dragComponentProperties: undefined
28 
29  readonly property bool recognisedPress: status == TouchGestureArea.Recognized &&
30  touchPoints.length >= minimumTouchPoints &&
31  touchPoints.length <= maximumTouchPoints
32  readonly property bool recognisedDrag: priv.wasRecognisedPress && dragging
33 
34  signal pressed(int x, int y)
35  signal clicked
36  signal dragStarted
37  signal dropped
38  signal cancelled
39 
40  onEnabledChanged: {
41  if (!enabled) {
42  if (priv.dragObject) root.cancelled();
43  priv.wasRecognisedDrag = false;
44  priv.wasRecognisedPress = false;
45  }
46  }
47 
48  onRecognisedPressChanged: {
49  if (recognisedPress) {
50  // get the app at the center of the gesture
51  var centerX = 0;
52  var centerY = 0;
53  for (var i = 0; i < touchPoints.length; i++) {
54  centerX += touchPoints[i].x;
55  centerY += touchPoints[i].y;
56  }
57  centerX = centerX/touchPoints.length;
58  centerY = centerY/touchPoints.length;
59 
60  pressed(centerX, centerY);
61  priv.wasRecognisedPress = true;
62  }
63  }
64 
65  onStatusChanged: {
66  if (status != TouchGestureArea.Recognized) {
67  if (status == TouchGestureArea.Rejected) {
68  root.cancelled();
69  } else if (status == TouchGestureArea.WaitingForTouch) {
70  if (priv.wasRecognisedPress) {
71  if (!priv.wasRecognisedDrag) {
72  root.clicked();
73  } else {
74  root.dropped();
75  }
76  }
77  }
78  priv.wasRecognisedDrag = false;
79  priv.wasRecognisedPress = false;
80  }
81  }
82 
83  onRecognisedDragChanged: {
84  if (enableDrag && recognisedDrag) {
85  priv.wasRecognisedDrag = true;
86  root.dragStarted()
87  }
88  }
89 
90  QtObject {
91  id: priv
92  property var dragObject: null
93 
94  property bool wasRecognisedPress: false
95  property bool wasRecognisedDrag: false
96  }
97 
98  onCancelled: {
99  if (priv.dragObject) {
100  var obj = priv.dragObject;
101  priv.dragObject = null;
102 
103  obj.Drag.cancel();
104  obj.destroy();
105  }
106  }
107 
108  onDragStarted: {
109  if (!dragComponent)
110  return;
111 
112  if (dragComponentProperties) {
113  priv.dragObject = dragComponent.createObject(root, dragComponentProperties);
114  } else {
115  priv.dragObject = dragComponent.createObject(root);
116  }
117  priv.dragObject.Drag.start();
118  }
119 
120  onDropped: {
121  if (priv.dragObject) {
122  var obj = priv.dragObject;
123  priv.dragObject = null;
124 
125  obj.Drag.drop();
126  obj.destroy();
127  }
128  }
129 
130  Binding {
131  target: priv.dragObject
132  when: priv.dragObject && priv.wasRecognisedDrag
133  property: "x"
134  value: {
135  if (!priv.dragObject) return 0;
136  var sum = 0;
137  for (var i = 0; i < root.touchPoints.length; i++) {
138  sum += root.touchPoints[i].x;
139  }
140  return sum/root.touchPoints.length - priv.dragObject.width/2;
141  }
142  }
143 
144  Binding {
145  target: priv.dragObject
146  when: priv.dragObject && priv.wasRecognisedDrag
147  property: "y"
148  value: {
149  if (!priv.dragObject) return 0;
150  var sum = 0;
151  for (var i = 0; i < root.touchPoints.length; i++) {
152  sum += root.touchPoints[i].y;
153  }
154  return sum/root.touchPoints.length - priv.dragObject.height/2;
155  }
156  }
157 }