2 * Copyright (C) 2014-2015 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 Ubuntu.Components 1.3
20import Unity.Application 0.1 // for Mir.cursorName
21import "../Components/PanelState"
26 anchors.margins: -borderThickness
28 hoverEnabled: target && !target.maximized // don't grab the resize under the panel
30 property var windowStateStorage: WindowStateStorage
32 // The target item managed by this. Must be a parent or a sibling
33 // The area will anchor to it and manage move and resize events
34 property Item target: null
35 property string windowId: ""
36 property int borderThickness: 0
37 property int minWidth: 0
38 property int minHeight: 0
39 property int defaultWidth: units.gu(60)
40 property int defaultHeight: units.gu(50)
41 property int screenWidth: 0
42 property int screenHeight: 0
48 property int normalX: 0
49 property int normalY: 0
50 property int normalWidth: 0
51 property int normalHeight: 0
53 function updateNormalGeometry() {
54 if (root.target.state == "normal") {
55 normalX = root.target.x
56 normalY = root.target.y
57 normalWidth = root.target.width
58 normalHeight = root.target.height
65 onXChanged: priv.updateNormalGeometry();
66 onYChanged: priv.updateNormalGeometry();
67 onWidthChanged: priv.updateNormalGeometry();
68 onHeightChanged: priv.updateNormalGeometry();
71 Component.onCompleted: {
72 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
73 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
75 target.requestedWidth = Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth);
76 target.requestedHeight = Math.min(Math.max(windowGeometry.height, d.minimumHeight), root.screenHeight - PanelState.panelHeight);
77 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
78 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
80 var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal)
81 if (windowState === WindowStateStorage.WindowStateMaximized) {
82 target.maximize(false)
84 priv.updateNormalGeometry();
87 Component.onDestruction: {
88 windowStateStorage.saveState(root.windowId, target.state == "maximized" ? WindowStateStorage.WindowStateMaximized : WindowStateStorage.WindowStateNormal)
89 windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight))
95 readonly property int maxSafeInt: 2147483647
96 readonly property int maxSizeIncrement: units.gu(40)
98 readonly property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
99 onMinimumWidthChanged: {
100 if (target.requestedWidth < minimumWidth) {
101 target.requestedWidth = minimumWidth;
104 readonly property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight
105 onMinimumHeightChanged: {
106 if (target.requestedHeight < minimumHeight) {
107 target.requestedHeight = minimumHeight;
110 readonly property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0
111 ? root.target.maximumWidth : maxSafeInt
112 onMaximumWidthChanged: {
113 if (target.requestedWidth > maximumWidth) {
114 target.requestedWidth = maximumWidth;
117 readonly property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0
118 ? root.target.maximumHeight : maxSafeInt
119 onMaximumHeightChanged: {
120 if (target.requestedHeight > maximumHeight) {
121 target.requestedHeight = maximumHeight;
124 readonly property int widthIncrement: {
128 if (root.target.widthIncrement > 0) {
129 if (root.target.widthIncrement < maxSizeIncrement) {
130 return root.target.widthIncrement;
132 return maxSizeIncrement;
138 readonly property int heightIncrement: {
142 if (root.target.heightIncrement > 0) {
143 if (root.target.heightIncrement < maxSizeIncrement) {
144 return root.target.heightIncrement;
146 return maxSizeIncrement;
153 property bool leftBorder: false
154 property bool rightBorder: false
155 property bool topBorder: false
156 property bool bottomBorder: false
158 // true - A change in surface size will cause the left border of the window to move accordingly.
159 // The window's right border will stay in the same position.
160 // false - a change in surface size will cause the right border of the window to move accordingly.
161 // The window's left border will stay in the same position.
162 property bool moveLeftBorder: false
164 // true - A change in surface size will cause the top border of the window to move accordingly.
165 // The window's bottom border will stay in the same position.
166 // false - a change in surface size will cause the bottom border of the window to move accordingly.
167 // The window's top border will stay in the same position.
168 property bool moveTopBorder: false
170 property bool dragging: false
171 property real startMousePosX
172 property real startMousePosY
175 property real startWidth
176 property real startHeight
177 property real currentWidth
178 property real currentHeight
180 property string cursorName: {
181 if (root.containsMouse || root.pressed) {
182 if (leftBorder && !topBorder && !bottomBorder) {
184 } else if (rightBorder && !topBorder && !bottomBorder) {
186 } else if (topBorder && !leftBorder && !rightBorder) {
188 } else if (bottomBorder && !leftBorder && !rightBorder) {
189 return "bottom_side";
190 } else if (leftBorder && topBorder) {
191 return "top_left_corner";
192 } else if (leftBorder && bottomBorder) {
193 return "bottom_left_corner";
194 } else if (rightBorder && topBorder) {
195 return "top_right_corner";
196 } else if (rightBorder && bottomBorder) {
197 return "bottom_right_corner";
205 onCursorNameChanged: {
206 Mir.cursorName = cursorName;
209 function updateBorders() {
210 leftBorder = mouseX <= borderThickness;
211 rightBorder = mouseX >= width - borderThickness;
212 topBorder = mouseY <= borderThickness;
213 bottomBorder = mouseY >= height - borderThickness;
218 id: resetBordersToMoveTimer
221 d.moveLeftBorder = false;
222 d.moveTopBorder = false;
227 var pos = mapToItem(target.parent, mouseX, mouseY);
231 resetBordersToMoveTimer.stop();
232 d.moveLeftBorder = d.leftBorder;
233 d.moveTopBorder = d.topBorder;
235 var pos = mapToItem(root.target.parent, mouseX, mouseY);
236 d.startMousePosX = pos.x;
237 d.startMousePosY = pos.y;
240 d.startWidth = target.width;
241 d.startHeight = target.height;
242 d.currentWidth = target.width;
243 d.currentHeight = target.height;
246 resetBordersToMoveTimer.start();
269 var pos = mapToItem(target.parent, mouse.x, mouse.y);
271 var deltaX = Math.floor((pos.x - d.startMousePosX) / d.widthIncrement) * d.widthIncrement;
272 var deltaY = Math.floor((pos.y - d.startMousePosY) / d.heightIncrement) * d.heightIncrement;
275 var newTargetX = d.startX + deltaX;
276 var rightBorderX = target.x + target.width;
277 if (rightBorderX > newTargetX + d.minimumWidth) {
278 if (rightBorderX < newTargetX + d.maximumWidth) {
279 target.requestedWidth = rightBorderX - newTargetX;
281 target.requestedWidth = d.maximumWidth;
284 target.requestedWidth = d.minimumWidth;
287 } else if (d.rightBorder) {
288 var newWidth = d.startWidth + deltaX;
289 if (newWidth > d.minimumWidth) {
290 if (newWidth < d.maximumWidth) {
291 target.requestedWidth = newWidth;
293 target.requestedWidth = d.maximumWidth;
296 target.requestedWidth = d.minimumWidth;
301 var newTargetY = d.startY + deltaY;
302 var bottomBorderY = target.y + target.height;
303 if (bottomBorderY > newTargetY + d.minimumHeight) {
304 if (bottomBorderY < newTargetY + d.maximumHeight) {
305 target.requestedHeight = bottomBorderY - newTargetY;
307 target.requestedHeight = d.maximumHeight;
310 target.requestedHeight = d.minimumHeight;
313 } else if (d.bottomBorder) {
314 var newHeight = d.startHeight + deltaY;
315 if (newHeight > d.minimumHeight) {
316 if (newHeight < d.maximumHeight) {
317 target.requestedHeight = newHeight;
319 target.requestedHeight = d.maximumHeight;
322 target.requestedHeight = d.minimumHeight;
330 if (d.moveLeftBorder) {
331 target.x += d.currentWidth - target.width;
333 d.currentWidth = target.width;
336 if (d.moveTopBorder) {
337 target.y += d.currentHeight - target.height;
339 d.currentHeight = target.height;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list