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/>.
16 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
20 import QtQuick.Layouts 1.1
21 import Ubuntu.Components 1.1
22 import Unity.Application 0.1
23 import "../Components"
24 import "../Components/PanelState"
26 import Ubuntu.Gestures 0.1
32 // Controls to be set from outside
33 property int dragAreaWidth // just to comply with the interface shared between stages
34 property real maximizedAppTopMargin
35 property bool interactive
36 property bool spreadEnabled // just to comply with the interface shared between stages
37 property real inverseProgress: 0 // just to comply with the interface shared between stages
38 property int shellOrientationAngle: 0
39 property int shellOrientation
40 property int shellPrimaryOrientation
41 property int nativeOrientation
42 property bool beingResized: false
43 property bool keepDashRunning: true
44 property bool suspended: false
45 property alias background: wallpaper.source
46 property alias altTabPressed: spread.altTabPressed
48 // functions to be called from outside
49 function updateFocusedAppOrientation() { /* TODO */ }
50 function updateFocusedAppOrientationAnimated() { /* TODO */}
52 // To be read from outside
53 readonly property var mainApp: ApplicationManager.focusedApplicationId
54 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
56 property int mainAppWindowOrientationAngle: 0
57 readonly property bool orientationChangesEnabled: false
60 target: ApplicationManager
62 if (spread.state == "altTab") {
66 ApplicationManager.requestFocusApplication(appId)
70 var appIndex = priv.indexOf(appId);
71 var appDelegate = appRepeater.itemAt(appIndex);
72 appDelegate.minimized = false;
73 ApplicationManager.focusApplication(appId)
75 if (spread.state == "altTab") {
84 readonly property string focusedAppId: ApplicationManager.focusedApplicationId
85 readonly property var focusedAppDelegate: {
86 var index = indexOf(focusedAppId);
87 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
90 function indexOf(appId) {
91 for (var i = 0; i < ApplicationManager.count; i++) {
92 if (ApplicationManager.get(i).appId == appId) {
103 ApplicationManager.stopApplication(ApplicationManager.focusedApplicationId)
105 onMinimize: appRepeater.itemAt(0).minimize();
106 onMaximize: appRepeater.itemAt(0).unmaximize();
111 property: "buttonsVisible"
112 value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.state === "maximized"
117 objectName: "appContainer"
119 focus: spread.state !== "altTab"
124 sourceSize { height: root.height; width: root.width }
125 fillMode: Image.PreserveAspectCrop
130 model: ApplicationManager
131 objectName: "appRepeater"
133 delegate: FocusScope {
135 z: ApplicationManager.count - index
139 focus: model.appId === priv.focusedAppId
141 readonly property int minWidth: units.gu(10)
142 readonly property int minHeight: units.gu(10)
144 property bool maximized: false
145 property bool minimized: false
148 if (focus && ApplicationManager.focusedApplicationId !== model.appId) {
149 ApplicationManager.focusApplication(model.appId);
154 target: ApplicationManager.get(index)
155 property: "requestedState"
156 // TODO: figure out some lifecycle policy, like suspending minimized apps
157 // if running on a tablet or something.
158 // TODO: If the device has a dozen suspended apps because it was running
159 // in staged mode, when it switches to Windowed mode it will suddenly
160 // resume all those apps at once. We might want to avoid that.
161 value: ApplicationInfoInterface.RequestedRunning // Always running for now
164 function maximize() {
168 function minimize() {
172 function unmaximize() {
179 name: "normal"; when: !appDelegate.maximized && !appDelegate.minimized
182 name: "maximized"; when: appDelegate.maximized
183 PropertyChanges { target: appDelegate; x: 0; y: 0; width: root.width; height: root.height }
186 name: "minimized"; when: appDelegate.minimized
187 PropertyChanges { target: appDelegate; x: -appDelegate.width / 2; scale: units.gu(5) / appDelegate.width; opacity: 0 }
192 from: "maximized,minimized,normal,"
193 to: "maximized,minimized,normal,"
194 PropertyAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale" }
199 PropertyAction { target: appDelegate; properties: "y,angle,z,itemScale,itemScaleOriginY" }
200 PropertyAction { target: decoratedWindow; properties: "anchors.topMargin" }
202 target: appDelegate; properties: "x"
204 duration: rightEdgePushArea.containsMouse ? UbuntuAnimation.FastDuration :0
205 easing: UbuntuAnimation.StandardEasing
214 value: ApplicationManager.count + 1
215 when: index == spread.highlightedIndex && blurLayer.ready
218 WindowMoveResizeArea {
219 id: windowMoveResizeArea
221 minWidth: appDelegate.minWidth
222 minHeight: appDelegate.minHeight
223 resizeHandleWidth: units.gu(2)
224 windowId: model.appId // FIXME: Change this to point to windowId once we have such a thing
226 onPressed: { ApplicationManager.focusApplication(model.appId) }
231 objectName: "decoratedWindow"
232 anchors.left: appDelegate.left
233 anchors.top: appDelegate.top
234 width: appDelegate.width
235 height: appDelegate.height
236 application: ApplicationManager.get(index)
237 active: ApplicationManager.focusedApplicationId === model.appId
240 onClose: ApplicationManager.stopApplication(model.appId)
241 onMaximize: appDelegate.maximize()
242 onMinimize: appDelegate.minimize()
265 visible: spreadBackground.visible
273 workspace: appContainer
274 focus: state == "altTab"