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/>.
18 import Ubuntu.Components 1.3
19 import Unity.Application 0.1
20 import "Spread/MathUtils.js" as MathUtils
25 // The DecoratedWindow takes requestedWidth/requestedHeight and asks its surface to be resized to that
26 // (minus the window decoration size in case hasDecoration and showDecoration are true)
27 // The surface might not be able to resize to the requested values. It will return its actual size
28 // in implicitWidth/implicitHeight.
30 property alias application: applicationWindow.application
31 property alias surface: applicationWindow.surface
32 readonly property alias focusedSurface: applicationWindow.focusedSurface
33 property alias active: decoration.active
34 readonly property alias title: applicationWindow.title
35 property alias maximizeButtonShown: decoration.maximizeButtonShown
36 property alias interactive: applicationWindow.interactive
37 readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled
39 // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account.
40 property bool hasDecoration: true
41 // This will temporarily show/hide the decoration without actually changing the surface's dimensions
42 property real showDecoration: 1
43 property bool animateDecoration: false
44 property bool showHighlight: false
45 property int highlightSize: units.gu(1)
46 property real shadowOpacity: 0
47 property bool darkening: false
49 property real requestedWidth
50 property real requestedHeight
51 property real scaleToPreviewProgress: 0
52 property int scaleToPreviewSize: units.gu(30)
54 property alias surfaceOrientationAngle: applicationWindow.surfaceOrientationAngle
55 readonly property real decorationHeight: Math.min(d.visibleDecorationHeight, d.requestedDecorationHeight)
56 readonly property bool counterRotate: surfaceOrientationAngle != 0 && surfaceOrientationAngle != 180
58 readonly property int minimumWidth: !counterRotate ? applicationWindow.minimumWidth : applicationWindow.minimumHeight
59 readonly property int minimumHeight: decorationHeight + (!counterRotate ? applicationWindow.minimumHeight : applicationWindow.minimumWidth)
60 readonly property int maximumWidth: !counterRotate ? applicationWindow.maximumWidth : applicationWindow.maximumHeight
61 readonly property int maximumHeight: (root.decorationShown && applicationWindow.maximumHeight > 0 ? decoration.height : 0)
62 + (!counterRotate ? applicationWindow.maximumHeight : applicationWindow.maximumWidth)
63 readonly property int widthIncrement: !counterRotate ? applicationWindow.widthIncrement : applicationWindow.heightIncrement
64 readonly property int heightIncrement: !counterRotate ? applicationWindow.heightIncrement : applicationWindow.widthIncrement
66 property alias overlayShown: decoration.overlayShown
67 property alias stageWidth: moveHandler.stageWidth
68 property alias stageHeight: moveHandler.stageHeight
69 readonly property alias dragging: moveHandler.dragging
71 readonly property Item clientAreaItem: applicationWindow
74 signal maximizeClicked()
75 signal maximizeHorizontallyClicked()
76 signal maximizeVerticallyClicked()
77 signal minimizeClicked()
78 signal decorationPressed()
79 signal decorationReleased()
83 property int requestedDecorationHeight: root.hasDecoration ? decoration.height : 0
84 Behavior on requestedDecorationHeight { enabled: root.animateDecoration; UbuntuNumberAnimation { } }
86 property int visibleDecorationHeight: root.hasDecoration ? root.showDecoration * decoration.height : 0
87 Behavior on visibleDecorationHeight { enabled: root.animateDecoration; UbuntuNumberAnimation { } }
93 name: "normal"; when: root.scaleToPreviewProgress <= 0 && root.application.state === ApplicationInfoInterface.Running
96 implicitWidth: counterRotate ? applicationWindow.implicitHeight : applicationWindow.implicitWidth
97 implicitHeight: root.decorationHeight + (counterRotate ? applicationWindow.implicitWidth: applicationWindow.implicitHeight)
101 name: "normalSuspended"; when: root.scaleToPreviewProgress <= 0 && root.application.state !== ApplicationInfoInterface.Running
105 implicitWidth: counterRotate ? applicationWindow.requestedHeight : applicationWindow.requestedWidth
106 implicitHeight: root.decorationHeight + (counterRotate ? applicationWindow.requestedWidth: applicationWindow.requestedHeight)
110 name: "preview"; when: root.scaleToPreviewProgress > 0
113 implicitWidth: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedWidth, root.scaleToPreviewSize, root.scaleToPreviewProgress)
114 implicitHeight: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedHeight, root.scaleToPreviewSize, root.scaleToPreviewProgress)
117 target: applicationWindow;
118 requestedWidth: applicationWindow.oldRequestedWidth
119 requestedHeight: applicationWindow.oldRequestedHeight
120 width: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedWidth, applicationWindow.minSize, root.scaleToPreviewProgress)
121 height: MathUtils.linearAnimation(0, 1, applicationWindow.oldRequestedHeight, applicationWindow.minSize, root.scaleToPreviewProgress)
122 itemScale: root.implicitWidth / width
129 id: selectionHighlight
130 objectName: "selectionHighlight"
132 anchors.margins: -root.highlightSize
134 opacity: showHighlight ? 0.55 : 0
141 left: parent.left; top: parent.top; right: parent.right
142 margins: active ? -units.gu(2) : -units.gu(1.5)
144 height: Math.min(applicationWindow.implicitHeight, applicationWindow.height) * applicationWindow.itemScale
145 + root.decorationHeight * Math.min(1, root.showDecoration) + (active ? units.gu(4) : units.gu(3))
146 source: "../graphics/dropshadow2gu.sci"
147 opacity: root.shadowOpacity
152 closeButtonVisible: root.application.appId !== "unity8-dash"
153 objectName: "appWindowDecoration"
154 anchors { left: parent.left; top: parent.top; right: parent.right }
157 title: applicationWindow.title
158 opacity: root.hasDecoration ? Math.min(1, root.showDecoration) : 0
160 Behavior on opacity { UbuntuNumberAnimation { } }
162 onCloseClicked: root.closeClicked();
163 onMaximizeClicked: { root.decorationPressed(); root.maximizeClicked(); }
164 onMaximizeHorizontallyClicked: { root.decorationPressed(); root.maximizeHorizontallyClicked(); }
165 onMaximizeVerticallyClicked: { root.decorationPressed(); root.maximizeVerticallyClicked(); }
166 onMinimizeClicked: root.minimizeClicked();
167 onPressed: root.decorationPressed();
169 onPressedChanged: moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY)
170 onPositionChanged: moveHandler.handlePositionChanged(mouse)
172 root.decorationReleased();
173 moveHandler.handleReleased();
179 objectName: "moveHandler"
181 buttonsWidth: decoration.buttonsWidth
185 id: applicationWindow
186 objectName: "appWindow"
187 anchors.left: parent.left
188 anchors.top: parent.top
189 anchors.topMargin: root.decorationHeight * Math.min(1, root.showDecoration)
191 height: implicitHeight
192 requestedHeight: !counterRotate ? root.requestedHeight - d.requestedDecorationHeight : root.requestedWidth
193 requestedWidth: !counterRotate ? root.requestedWidth : root.requestedHeight - d.requestedDecorationHeight
194 property int oldRequestedWidth: requestedWidth
195 property int oldRequestedHeight: requestedHeight
196 onRequestedWidthChanged: oldRequestedWidth = requestedWidth
197 onRequestedHeightChanged: oldRequestedHeight = requestedHeight
200 property real itemScale: 1
201 property real minSize: Math.min(root.scaleToPreviewSize, Math.min(requestedHeight, Math.min(requestedWidth, Math.min(implicitHeight, implicitWidth))))
205 id: rotationTransform
206 readonly property int rotationAngle: applicationWindow.application &&
207 applicationWindow.application.rotatesWindowContents
208 ? ((360 - applicationWindow.surfaceOrientationAngle) % 360) : 0
210 if (rotationAngle == 90) return applicationWindow.height / 2;
211 else if (rotationAngle == 270) return applicationWindow.width / 2;
212 else if (rotationAngle == 180) return applicationWindow.width / 2;
216 if (rotationAngle == 90) return applicationWindow.height / 2;
217 else if (rotationAngle == 270) return applicationWindow.width / 2;
218 else if (rotationAngle == 180) return applicationWindow.height / 2;
224 xScale: applicationWindow.itemScale
225 yScale: applicationWindow.itemScale
231 anchors.fill: applicationWindow
232 acceptedButtons: Qt.LeftButton
233 property bool dragging: false
234 cursorShape: undefined // don't interfere with the cursor shape set by the underlying MirSurfaceItem
236 if (mouse.button == Qt.LeftButton && mouse.modifiers == Qt.AltModifier) {
237 root.decorationPressed(); // to raise it
238 moveHandler.handlePressedChanged(true, Qt.LeftButton, mouse.x, mouse.y);
240 mouse.accepted = true;
242 mouse.accepted = false;
247 moveHandler.handlePositionChanged(mouse);
252 moveHandler.handlePressedChanged(false, Qt.LeftButton);
253 root.decorationReleased(); // commits the fake preview max rectangle
254 moveHandler.handleReleased();
263 opacity: root.darkening && !root.showHighlight ? 0.05 : 0
264 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }