Unity 8
WindowMoveResizeArea.qml
1 /*
2  * Copyright (C) 2014-2015 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  * Authors: Michael Zanetti <michael.zanetti@canonical.com>
17  */
18 
19 import QtQuick 2.3
20 import Ubuntu.Components 1.1
21 import Utils 0.1
22 
23 MouseArea {
24  id: root
25  anchors.fill: target
26  anchors.margins: -resizeHandleWidth
27 
28  property var windowStateStorage: WindowStateStorage
29 
30  // The target item managed by this. Must be a parent or a sibling
31  // The area will anchor to it and manage move and resize events
32  property Item target: null
33  property string windowId: ""
34  property int resizeHandleWidth: 0
35  property int minWidth: 0
36  property int minHeight: 0
37 
38  QtObject {
39  id: priv
40  readonly property int windowWidth: root.width - root.resizeHandleWidth * 2
41  readonly property int windowHeight: root.height - resizeHandleWidth * 2
42 
43  property var startPoint
44 
45  property bool resizeTop: false
46  property bool resizeBottom: false
47  property bool resizeLeft: false
48  property bool resizeRight: false
49 
50  }
51 
52  Component.onCompleted: {
53  var windowState = windowStateStorage.getGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height))
54  if (windowState !== undefined) {
55  target.x = windowState.x
56  target.y = windowState.y
57  target.width = windowState.width
58  target.height = windowState.height
59  }
60  }
61 
62  onPressed: {
63  priv.startPoint = Qt.point(mouse.x, mouse.y);
64  priv.resizeTop = mouseY < root.resizeHandleWidth;
65  priv.resizeBottom = mouseY > (root.height - root.resizeHandleWidth);
66  priv.resizeLeft = mouseX < root.resizeHandleWidth;
67  priv.resizeRight = mouseX > (root.width - root.resizeHandleWidth);
68  }
69 
70  onPositionChanged: {
71  var currentPoint = Qt.point(mouse.x, mouse.y);
72  var mouseDiff = Qt.point(currentPoint.x - priv.startPoint.x, currentPoint.y - priv.startPoint.y);
73  var moveDiff = Qt.point(0, 0);
74  var sizeDiff = Qt.point(0, 0);
75  var maxSizeDiff = Qt.point(root.minWidth - root.target.width, root.minHeight - root.target.height)
76 
77  if (priv.resizeTop || priv.resizeBottom || priv.resizeLeft || priv.resizeRight) {
78  if (priv.resizeTop) {
79  sizeDiff.y = Math.max(maxSizeDiff.y, -currentPoint.y + priv.startPoint.y)
80  moveDiff.y = -sizeDiff.y
81  }
82  if (priv.resizeBottom) {
83  sizeDiff.y = Math.max(maxSizeDiff.y, currentPoint.y - priv.startPoint.y)
84  priv.startPoint.y += sizeDiff.y
85  }
86  if (priv.resizeLeft) {
87  sizeDiff.x = Math.max(maxSizeDiff.x, -currentPoint.x + priv.startPoint.x)
88  moveDiff.x = -sizeDiff.x
89  }
90  if (priv.resizeRight) {
91  sizeDiff.x = Math.max(maxSizeDiff.x, currentPoint.x - priv.startPoint.x)
92  priv.startPoint.x += sizeDiff.x
93  }
94 
95  target.x += moveDiff.x;
96  target.y += moveDiff.y;
97  target.width += sizeDiff.x;
98  target.height += sizeDiff.y;
99  } else {
100  target.x += mouseDiff.x;
101  target.y += mouseDiff.y;
102  }
103 
104  }
105 
106  Component.onDestruction: {
107  windowStateStorage.saveGeometry(root.windowId, Qt.rect(target.x, target.y, target.windowWidth, target.windowHeight))
108  }
109 }