@@ -27,8 +27,8 @@ Item {
2727
2828 // to be set from outside
2929 property Item target // appDelegate
30− property int stageWidth
31− property int stageHeight
30+ property alias stageWidth: moveHandler.stageWidth
31+ property alias stageHeight: moveHandler.stageHeight
3232
3333 // to be read from outside
3434 readonly property alias overlayShown: overlay.visible
@@ -63,16 +63,17 @@ Item {
6363 readonly property bool recognizedDrag: recognizedPress && dragging
6464 onRecognizedDragChanged: {
6565 if (recognizedDrag) {
66− priv.handlePressedChanged(true, tp.x, tp.y);
67− } else if (!moveHandler.containsPress) { // prevent interfering with the central piece drag/move
68− priv.dragging = false;
66+ moveHandler.handlePressedChanged(true, Qt.LeftButton, tp.x, tp.y);
67+ } else if (!mouseArea.containsPress) { // prevent interfering with the central piece drag/move
68+ // FIXME!!!
69+ moveHandler.handlePressedChanged(false, Qt.LeftButton, tp.x, tp.y);
6970 }
7071 }
7172
7273 readonly property point tp: recognizedPress ? Qt.point(touchPoints[0].x, touchPoints[0].y) : Qt.point(-1, -1)
7374 onUpdated: {
7475 if (recognizedDrag) {
75− priv.handlePositionChanged(tp.x, tp.y);
76+ moveHandler.handlePositionChanged(tp);
7677 }
7778 }
7879 }
@@ -81,74 +82,13 @@ Item {
8182 Timer {
8283 id: overlayTimer
8384 interval: 2000
84− repeat: priv.dragging || (priv.resizeArea && priv.resizeArea.dragging)
85+ repeat: moveHandler.dragging || (priv.resizeArea && priv.resizeArea.dragging)
8586 }
8687
8788 QtObject {
8889 id: priv
89− property real distanceX
90− property real distanceY
91− property bool dragging
92−
9390 readonly property var resizeArea: root.target && root.target.resizeArea ? root.target.resizeArea : null
9491 readonly property bool ensureWindow: root.target.state == "normal" || root.target.state == "restored"
95−
96− readonly property int triggerArea: units.gu(8)
97− property bool nearLeftEdge: target.maximizedLeft
98− property bool nearTopEdge: target.maximized
99− property bool nearRightEdge: target.maximizedRight
100− property bool nearTopLeftCorner: target.maximizedTopLeft
101− property bool nearTopRightCorner: target.maximizedTopRight
102− property bool nearBottomLeftCorner: target.maximizedBottomLeft
103− property bool nearBottomRightCorner: target.maximizedBottomRight
104−
105− function resetEdges() {
106− nearLeftEdge = false;
107− nearRightEdge = false;
108− nearTopEdge = false;
109− nearTopLeftCorner = false;
110− nearTopRightCorner = false;
111− nearBottomLeftCorner = false;
112− nearBottomRightCorner = false;
113− }
114−
115− function handlePressedChanged(pressed, mouseX, mouseY) {
116− if (pressed) {
117− var pos = mapToItem(root.target, mouseX, mouseY);
118− priv.distanceX = pos.x;
119− priv.distanceY = pos.y;
120− priv.dragging = true;
121− } else {
122− priv.dragging = false;
123− }
124− }
125−
126− function handlePositionChanged(mouseX, mouseY) {
127− var pos = mapToItem(root.target.parent, mouseX, mouseY);
128− root.target.requestedX = Math.round(pos.x - priv.distanceX);
129− root.target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
130− }
131−
132− function saveRestoredPos(x, y) {
133− var pos = mapToItem(root.target, x, y);
134− target.restoredX = Math.round(pos.x);
135− target.restoredY = Math.round(pos.y);
136− }
137−
138− // return the progress of mouse pointer movement from 0 to 1 within a corner square of the screen
139− // 0 -> before the mouse enters the square
140− // 1 -> mouse is exactly in the very corner
141− // a is the corner, b is the mouse pos
142− function progressInCorner(ax, ay, bx, by) {
143− // distance of two points, a and b, in pixels
144− var distance = Math.sqrt(Math.pow(bx-ax, 2) + Math.pow(by-ay, 2));
145− // length of the triggerArea square diagonal
146− var diagLength = Math.sqrt(2 * priv.triggerArea * priv.triggerArea);
147− var ratio = 1 - (distance / diagLength);
148− return bx > 0 && bx <= stageWidth && by > 0 && by <= stageHeight ? ratio : 1; // everything "outside" of our square from the center is 1
149− }
150−
151− property real progress: 0
15292 }
15393
15494 // the visual overlay
@@ -174,106 +114,32 @@ Item {
174114
175115 // move handler
176116 MouseArea {
177− id: moveHandler
117+ id: mouseArea
178118 anchors.fill: parent
179119 visible: overlay.visible
180120 enabled: visible
181121 hoverEnabled: true
182− cursorShape: priv.dragging ? Qt.ClosedHandCursor : (overlay.visible ? Qt.OpenHandCursor : Qt.ArrowCursor)
122+ cursorShape: moveHandler.dragging ? Qt.ClosedHandCursor : (overlay.visible ? Qt.OpenHandCursor : Qt.ArrowCursor)
183123
184− onPressedChanged: priv.handlePressedChanged(pressed, mouseX, mouseY)
185− onPositionChanged: {
186− if (priv.dragging) {
187− priv.handlePositionChanged(mouseX, mouseY);
124+ onPressedChanged: moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY)
125+ onPositionChanged: moveHandler.handlePositionChanged(mouse)
126+ onReleased: moveHandler.handleReleased(mouse)
127+ }
188128
189− var globalPos = mapToItem(null, mouseX, mouseY);
190− var globalX = globalPos.x;
191− var globalY = globalPos.y;
192− if (globalX < priv.triggerArea && globalY < PanelState.panelHeight) { // top left
193− if (target.canBeCornerMaximized) {
194− priv.progress = priv.progressInCorner(0, PanelState.panelHeight, globalX, globalY);
195− priv.resetEdges();
196− priv.nearTopLeftCorner = true;
197− root.fakeMaximizeTopLeftAnimationRequested(priv.progress);
198− }
199− } else if (globalX > stageWidth - priv.triggerArea && globalY < PanelState.panelHeight) { // top right
200− if (target.canBeCornerMaximized) {
201− priv.progress = priv.progressInCorner(stageWidth, PanelState.panelHeight, globalX, globalY);
202− priv.resetEdges();
203− priv.nearTopRightCorner = true;
204− root.fakeMaximizeTopRightAnimationRequested(priv.progress);
205− }
206− } else if (globalX < priv.triggerArea && globalY > stageHeight - priv.triggerArea) { // bottom left
207− if (target.canBeCornerMaximized) {
208− priv.progress = priv.progressInCorner(0, stageHeight, globalX, globalY);
209− priv.resetEdges();
210− priv.nearBottomLeftCorner = true;
211− root.fakeMaximizeBottomLeftAnimationRequested(priv.progress);
212− }
213− } else if (globalX > stageWidth - priv.triggerArea && globalY > stageHeight - priv.triggerArea) { // bottom right
214− if (target.canBeCornerMaximized) {
215− priv.progress = priv.progressInCorner(stageWidth, stageHeight, globalX, globalY);
216− priv.resetEdges();
217− priv.nearBottomRightCorner = true;
218− root.fakeMaximizeBottomRightAnimationRequested(priv.progress);
219− }
220− } else if (globalX < priv.triggerArea) { // left
221− if (target.canBeMaximizedLeftRight) {
222− priv.progress = MathUtils.clampAndProject(globalX, priv.triggerArea, 0, 0, 1);
223− priv.resetEdges();
224− priv.nearLeftEdge = true;
225− root.fakeMaximizeLeftAnimationRequested(priv.progress);
226− }
227− } else if (globalX > stageWidth - priv.triggerArea) { // right
228− if (target.canBeMaximizedLeftRight) {
229− priv.progress = MathUtils.clampAndProject(globalX, stageWidth - priv.triggerArea, stageWidth, 0, 1);
230− priv.resetEdges();
231− priv.nearRightEdge = true;
232− root.fakeMaximizeRightAnimationRequested(priv.progress);
233− }
234− } else if (globalY < PanelState.panelHeight) { // top
235− if (target.canBeMaximized) {
236− priv.progress = MathUtils.clampAndProject(globalY, Math.max(PanelState.panelHeight, priv.triggerArea), 0, 0, 1);
237− priv.resetEdges();
238− priv.nearTopEdge = true;
239− root.fakeMaximizeAnimationRequested(priv.progress);
240− }
241− } else if (priv.nearLeftEdge || priv.nearRightEdge || priv.nearTopEdge || priv.nearTopLeftCorner || priv.nearTopRightCorner ||
242− priv.nearBottomLeftCorner || priv.nearBottomRightCorner) {
243− print("!!! Exited")
244− priv.progress = 0;
245− priv.resetEdges();
246− root.stopFakeAnimation();
247− } else if (target.anyMaximized) {
248− priv.progress = 0;
249− target.restoreFromMaximized();
250− }
251− }
252− }
253− onReleased: {
254− print("Mouse released (left/top/right)", priv.nearLeftEdge, priv.nearTopEdge, priv.nearRightEdge)
255− if (mouse.button == Qt.LeftButton && (target.state == "normal" || target.state == "restored") && priv.progress == 0) {
256− priv.saveRestoredPos(target.x, target.y);
257− } else if (priv.progress < 0.3) { // cancel the preview shape if under 30%
258− priv.progress = 0;
259− priv.resetEdges();
260− root.stopFakeAnimation();
261− } else if (priv.nearLeftEdge) {
262− target.maximizeLeft();
263− } else if (priv.nearTopEdge) {
264− target.maximize();
265− } else if (priv.nearRightEdge) {
266− target.maximizeRight();
267− } else if (priv.nearTopLeftCorner) {
268− target.maximizeTopLeft();
269− } else if (priv.nearTopRightCorner) {
270− target.maximizeTopRight();
271− } else if (priv.nearBottomLeftCorner) {
272− target.maximizeBottomLeft();
273− } else if (priv.nearBottomRightCorner) {
274− target.maximizeBottomRight();
275− }
276− }
129+ MoveHandler {
130+ id: moveHandler
131+ anchors.fill: mouseArea
132+ objectName: "moveHandler"
133+ target: root.target
134+
135+ onFakeMaximizeAnimationRequested: root.fakeMaximizeAnimationRequested(progress)
136+ onFakeMaximizeLeftAnimationRequested: root.fakeMaximizeLeftAnimationRequested(progress)
137+ onFakeMaximizeRightAnimationRequested: root.fakeMaximizeRightAnimationRequested(progress)
138+ onFakeMaximizeTopLeftAnimationRequested: root.fakeMaximizeTopLeftAnimationRequested(progress)
139+ onFakeMaximizeTopRightAnimationRequested: root.fakeMaximizeTopRightAnimationRequested(progress)
140+ onFakeMaximizeBottomLeftAnimationRequested: root.fakeMaximizeBottomLeftAnimationRequested(progress)
141+ onFakeMaximizeBottomRightAnimationRequested: root.fakeMaximizeBottomRightAnimationRequested(progress)
142+ onStopFakeAnimation: root.stopFakeAnimation()
277143 }
278144
279145 // dismiss area