2 * Copyright (C) 2014-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 Unity.Application 0.1 // For Mir singleton
19import Ubuntu.Components 1.3
22import "../Components/PanelState"
27 property Item target // appDelegate
28 property int stageWidth
29 property int stageHeight
30 property real buttonsWidth: 0
32 readonly property bool 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()
43 property QtObject priv: QtObject {
44 property real distanceX
45 property real distanceY
46 property bool dragging
48 readonly property int triggerArea: units.gu(8)
49 property bool nearLeftEdge: target.maximizedLeft
50 property bool nearTopEdge: target.maximized
51 property bool nearRightEdge: target.maximizedRight
52 property bool nearTopLeftCorner: target.maximizedTopLeft
53 property bool nearTopRightCorner: target.maximizedTopRight
54 property bool nearBottomLeftCorner: target.maximizedBottomLeft
55 property bool nearBottomRightCorner: target.maximizedBottomRight
57 function resetEdges() {
59 nearRightEdge = false;
61 nearTopLeftCorner = false;
62 nearTopRightCorner = false;
63 nearBottomLeftCorner = false;
64 nearBottomRightCorner = false;
67 // return the progress of mouse pointer movement from 0 to 1 within a corner square of the screen
68 // 0 -> before the mouse enters the square
69 // 1 -> mouse is in the outer corner
70 // a is the corner, b is the mouse pos
71 function progressInCorner(ax, ay, bx, by) {
72 // distance of two points, a and b, in pixels
73 var distance = Math.sqrt(Math.pow(bx-ax, 2) + Math.pow(by-ay, 2));
74 // length of the triggerArea square diagonal
75 var diagLength = Math.sqrt(2 * priv.triggerArea * priv.triggerArea);
76 var ratio = 1 - (distance / diagLength);
77 return bx > 0 && bx <= stageWidth && by > 0 && by <= stageHeight ? ratio : 1; // everything "outside" of our square from the center is 1
79 property real progress: 0
82 function handlePressedChanged(pressed, pressedButtons, mouseX, mouseY) {
83 if (pressed && pressedButtons === Qt.LeftButton) {
84 var pos = mapToItem(target, mouseX, mouseY);
85 if (target.anyMaximized) {
86 // keep distanceX relative to the normal window width minus the window control buttons (+spacing)
87 // so that dragging it back doesn't make the window jump around to weird positions, away from the mouse pointer
88 priv.distanceX = MathUtils.clampAndProject(pos.x, 0, target.width, buttonsWidth, target.resizeArea.normalWidth);
89 priv.distanceY = MathUtils.clampAndProject(pos.y, 0, target.height, 0, target.resizeArea.normalHeight);
91 priv.distanceX = pos.x;
92 priv.distanceY = pos.y;
97 priv.dragging = false;
102 function handlePositionChanged(mouse, sensingPoints) {
104 Mir.cursorName = "grabbing";
106 // restore from maximized when dragging away from edges/corners; guard against inadvertent changes when going into maximized state
107 if (target.anyMaximized && !target.windowedTransitionRunning) {
109 target.restore(false, WindowStateStorage.WindowStateNormal);
112 var pos = mapToItem(target.parent, mouse.x, mouse.y);
113 // Use integer coordinate values to ensure that target is left in a pixel-aligned
114 // position. Mouse movement could have subpixel precision, yielding a fractional
116 target.windowedX = Math.round(pos.x - priv.distanceX);
117 target.windowedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
119 if (sensingPoints) { // edge/corner detection when dragging via the touch overlay
120 if (sensingPoints.topLeft.x < priv.triggerArea && sensingPoints.topLeft.y < PanelState.panelHeight + priv.triggerArea
121 && target.canBeCornerMaximized) { // top left
122 priv.progress = priv.progressInCorner(0, PanelState.panelHeight, sensingPoints.topLeft.x, sensingPoints.topLeft.y);
124 priv.nearTopLeftCorner = true;
125 root.fakeMaximizeTopLeftAnimationRequested(priv.progress);
126 } else if (sensingPoints.topRight.x > stageWidth - priv.triggerArea && sensingPoints.topRight.y < PanelState.panelHeight + priv.triggerArea
127 && target.canBeCornerMaximized) { // top right
128 priv.progress = priv.progressInCorner(stageWidth, PanelState.panelHeight, sensingPoints.topRight.x, sensingPoints.topRight.y);
130 priv.nearTopRightCorner = true;
131 root.fakeMaximizeTopRightAnimationRequested(priv.progress);
132 } else if (sensingPoints.bottomLeft.x < priv.triggerArea && sensingPoints.bottomLeft.y > stageHeight - priv.triggerArea
133 && target.canBeCornerMaximized) { // bottom left
134 priv.progress = priv.progressInCorner(0, stageHeight, sensingPoints.bottomLeft.x, sensingPoints.bottomLeft.y);
136 priv.nearBottomLeftCorner = true;
137 root.fakeMaximizeBottomLeftAnimationRequested(priv.progress);
138 } else if (sensingPoints.bottomRight.x > stageWidth - priv.triggerArea && sensingPoints.bottomRight.y > stageHeight - priv.triggerArea
139 && target.canBeCornerMaximized) { // bottom right
140 priv.progress = priv.progressInCorner(stageWidth, stageHeight, sensingPoints.bottomRight.x, sensingPoints.bottomRight.y);
142 priv.nearBottomRightCorner = true;
143 root.fakeMaximizeBottomRightAnimationRequested(priv.progress);
144 } else if (sensingPoints.left.x < priv.triggerArea && target.canBeMaximizedLeftRight) { // left
145 priv.progress = MathUtils.clampAndProject(sensingPoints.left.x, priv.triggerArea, 0, 0, 1);
147 priv.nearLeftEdge = true;
148 root.fakeMaximizeLeftAnimationRequested(priv.progress);
149 } else if (sensingPoints.right.x > stageWidth - priv.triggerArea && target.canBeMaximizedLeftRight) { // right
150 priv.progress = MathUtils.clampAndProject(sensingPoints.right.x, stageWidth - priv.triggerArea, stageWidth, 0, 1);
152 priv.nearRightEdge = true;
153 root.fakeMaximizeRightAnimationRequested(priv.progress);
154 } else if (sensingPoints.top.y < PanelState.panelHeight + priv.triggerArea && target.canBeMaximized) { // top
155 priv.progress = MathUtils.clampAndProject(sensingPoints.top.y, PanelState.panelHeight + priv.triggerArea, 0, 0, 1);
157 priv.nearTopEdge = true;
158 root.fakeMaximizeAnimationRequested(priv.progress);
159 } else if (priv.nearLeftEdge || priv.nearRightEdge || priv.nearTopEdge || priv.nearTopLeftCorner || priv.nearTopRightCorner ||
160 priv.nearBottomLeftCorner || priv.nearBottomRightCorner) {
163 root.stopFakeAnimation();
169 function handleReleased(touchMode) {
174 if ((target.state == "normal" || target.state == "restored") && priv.progress == 0) {
175 // save the x/y to restore to
176 target.restoredX = target.x;
177 target.restoredY = target.y;
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