2 * Copyright (C) 2016 Canonical Ltd.
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.
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.
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/>.
18import Lomiri.Components 1.3
19import Lomiri.Gestures 0.1
20import QtMir.Application 0.1
25 // to be set from outside
26 property Item target // appDelegate
27 property WindowResizeArea resizeArea
28 property Item boundsItem
30 // to be read from outside
31 readonly property alias overlayShown: overlay.visible
32 readonly property alias dragging: priv.dragging
34 signal fakeMaximizeAnimationRequested(real amount)
35 signal fakeMaximizeLeftAnimationRequested(real amount)
36 signal fakeMaximizeRightAnimationRequested(real amount)
37 signal fakeMaximizeTopLeftAnimationRequested(real amount)
38 signal fakeMaximizeTopRightAnimationRequested(real amount)
39 signal fakeMaximizeBottomLeftAnimationRequested(real amount)
40 signal fakeMaximizeBottomRightAnimationRequested(real amount)
41 signal stopFakeAnimation()
53 readonly property bool dragging: moveHandler.dragging || (root.resizeArea && root.resizeArea.dragging)
55 function getSensingPoints() {
58 for (var i = 0; i < gestureArea.touchPoints.length; i++) {
59 var pt = gestureArea.touchPoints[i];
64 var leftmost = Math.min.apply(Math, xPoints);
65 var rightmost = Math.max.apply(Math, xPoints);
66 var topmost = Math.min.apply(Math, yPoints);
67 var bottommost = Math.max.apply(Math, yPoints);
70 left: mapToItem(target.parent, leftmost, (topmost+bottommost)/2),
71 top: mapToItem(target.parent, (leftmost+rightmost)/2, topmost),
72 right: mapToItem(target.parent, rightmost, (topmost+bottommost)/2),
73 topLeft: mapToItem(target.parent, leftmost, topmost),
74 topRight: mapToItem(target.parent, rightmost, topmost),
75 bottomLeft: mapToItem(target.parent, leftmost, bottommost),
76 bottomRight: mapToItem(target.parent, rightmost, bottommost)
84 objectName: "windowControlsOverlay"
86 enabled: overlayTimer.running
88 opacity: enabled ? 0.95 : 0
91 LomiriNumberAnimation {}
95 source: "graphics/arrows-centre.png"
98 sourceSize: Qt.size(width, height)
99 anchors.centerIn: parent
100 visible: target && target.width > units.gu(12) && target.height > units.gu(12)
106 visible: overlay.visible
110 onPressedChanged: moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY)
111 onPositionChanged: moveHandler.handlePositionChanged(mouse)
114 moveHandler.handleReleased();
120 objectName: "moveHandler"
123 boundsItem: root.boundsItem
125 onFakeMaximizeAnimationRequested: root.fakeMaximizeAnimationRequested(amount)
126 onFakeMaximizeLeftAnimationRequested: root.fakeMaximizeLeftAnimationRequested(amount)
127 onFakeMaximizeRightAnimationRequested: root.fakeMaximizeRightAnimationRequested(amount)
128 onFakeMaximizeTopLeftAnimationRequested: root.fakeMaximizeTopLeftAnimationRequested(amount)
129 onFakeMaximizeTopRightAnimationRequested: root.fakeMaximizeTopRightAnimationRequested(amount)
130 onFakeMaximizeBottomLeftAnimationRequested: root.fakeMaximizeBottomLeftAnimationRequested(amount)
131 onFakeMaximizeBottomRightAnimationRequested: root.fakeMaximizeBottomRightAnimationRequested(amount)
132 onStopFakeAnimation: root.stopFakeAnimation()
138 visible: overlay.visible
141 if (gestureArea.recognizedPress || gestureArea.recognizedDrag) {
142 mouse.accepted = false;
147 mouse.accepted = root.contains(mapToItem(root.target.clientAreaItem, mouse.x, mouse.y));
149 propagateComposedEvents: true
153 ResizeGrip { // top left
154 anchors.horizontalCenter: parent.left
155 anchors.verticalCenter: parent.top
156 visible: root.enabled || target.maximizedBottomRight
157 resizeTarget: root.resizeArea
160 ResizeGrip { // top center
161 anchors.horizontalCenter: parent.horizontalCenter
162 anchors.verticalCenter: parent.top
164 visible: root.enabled || target.maximizedHorizontally || target.maximizedBottomLeft || target.maximizedBottomRight
165 resizeTarget: root.resizeArea
168 ResizeGrip { // top right
169 anchors.horizontalCenter: parent.right
170 anchors.verticalCenter: parent.top
172 visible: root.enabled || target.maximizedBottomLeft
173 resizeTarget: root.resizeArea
176 ResizeGrip { // right
177 anchors.horizontalCenter: parent.right
178 anchors.verticalCenter: parent.verticalCenter
180 visible: root.enabled || target.maximizedVertically || target.maximizedLeft ||
181 target.maximizedTopLeft || target.maximizedBottomLeft
182 resizeTarget: root.resizeArea
185 ResizeGrip { // bottom right
186 anchors.horizontalCenter: parent.right
187 anchors.verticalCenter: parent.bottom
188 visible: root.enabled || target.maximizedTopLeft
189 resizeTarget: root.resizeArea
192 ResizeGrip { // bottom center
193 anchors.horizontalCenter: parent.horizontalCenter
194 anchors.verticalCenter: parent.bottom
196 visible: root.enabled || target.maximizedHorizontally || target.maximizedTopLeft || target.maximizedTopRight
197 resizeTarget: root.resizeArea
200 ResizeGrip { // bottom left
201 anchors.horizontalCenter: parent.left
202 anchors.verticalCenter: parent.bottom
204 visible: root.enabled || target.maximizedTopRight
205 resizeTarget: root.resizeArea
209 anchors.horizontalCenter: parent.left
210 anchors.verticalCenter: parent.verticalCenter
212 visible: root.enabled || target.maximizedVertically || target.maximizedRight ||
213 target.maximizedTopRight || target.maximizedBottomRight
214 resizeTarget: root.resizeArea
222 // NB: for testing set to 2, not to clash with lomiri7 touch overlay controls
223 minimumTouchPoints: 3
224 maximumTouchPoints: minimumTouchPoints
226 readonly property bool recognizedPress: status == TouchGestureArea.Recognized &&
227 touchPoints.length >= minimumTouchPoints &&
228 touchPoints.length <= maximumTouchPoints
229 onRecognizedPressChanged: {
230 if (recognizedPress) {
232 overlayTimer.start();
236 readonly property bool recognizedDrag: recognizedPress && dragging
237 onRecognizedDragChanged: {
238 if (recognizedDrag) {
239 moveHandler.handlePressedChanged(true, Qt.LeftButton, tp.x, tp.y);
240 } else if (!mouseArea.containsPress) { // prevent interfering with the central piece drag/move
241 moveHandler.handlePressedChanged(false, Qt.LeftButton);
243 moveHandler.handleReleased(true);
247 readonly property point tp: recognizedPress ? Qt.point(touchPoints[0].x, touchPoints[0].y) : Qt.point(-1, -1)
249 if (recognizedDrag) {
250 moveHandler.handlePositionChanged(tp, priv.getSensingPoints());