Compositor.qml 11.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 *   Copyright 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Library General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

import QtQuick 2.0
21
import QtQuick.Layouts 1.0
Marco Martin's avatar
Marco Martin committed
22
import QtQml.Models 2.1
23 24 25 26
import org.kde.plasma.core 2.0 as PlasmaCore
import "WindowManagement.js" as WindowManagement

Rectangle {
27
    property alias showSplash: splash.visible
28
    property bool showPanel: true
29
    property alias showKeyboard: keyboardLayer.visible
30 31
    readonly property alias layers: layers
    readonly property real topBarHeight: units.iconSizes.small
Marco Martin's avatar
Marco Martin committed
32
    readonly property real bottomBarHeight: units.iconSizes.medium
33
    property var currentWindow: null
34
    property var shellWindow: null;
35

Marco Martin's avatar
Marco Martin committed
36 37
    onCurrentWindowChanged: {
        if (!currentWindow) {
38
            compositorRoot.state = "homeScreen";
Marco Martin's avatar
Marco Martin committed
39 40
            return;
        }
Marco Martin's avatar
Marco Martin committed
41
        compositorRoot.state = "application";
Marco Martin's avatar
Marco Martin committed
42 43
    }

44 45
    id: compositorRoot
    color: "black"
Marco Martin's avatar
Marco Martin committed
46
    state: "homeScreen"
47

48
    Image {
49
        id: splash
50 51 52 53 54
        anchors.fill: parent
        source: "klogo.png"
        sourceSize.width: width
        sourceSize.height: height
        fillMode: Image.PreserveAspectFit
55
        z: 1000
56 57
    }

58 59 60 61 62 63 64 65 66 67 68
    ListModel {
        id: surfaceModel
    }

    Connections {
        target: compositor
        onSurfaceMapped: WindowManagement.surfaceMapped(surface)
        onSurfaceUnmapped: WindowManagement.surfaceUnmapped(surface)
        onSurfaceDestroyed: WindowManagement.surfaceDestroyed(surface)
    }

69
    QtObject {
70
        readonly property alias desktop: desktopLayer
71
        readonly property alias windows: windowsLayerBackground
72
        readonly property alias panel: panelLayer
73
        readonly property alias keyboard: keyboardLayer
74 75

        id: layers
76
    }
77

78 79 80
    Item {
        id: desktopLayer
        anchors.fill: parent
Marco Martin's avatar
Marco Martin committed
81
        visible: true
82
    }
83

Marco Martin's avatar
Marco Martin committed
84 85
    Rectangle {
        id: windowsLayerBackground
86 87 88 89 90
        anchors {
            fill: parent
            topMargin: topBarHeight
            bottomMargin: bottomBarHeight
        }
91
        color: Qt.rgba(0, 0, 0, 0.9)
92 93 94 95
        function addWindow (window) {
            window.parent = windowsLayout
        }
        property bool switchMode: windowsZoom.scale < 1
Marco Martin's avatar
Marco Martin committed
96

97 98 99 100 101 102
        Item {
            id: windowsZoom
            anchors.fill: parent
            Flickable {
                id: windowsLayer
                anchors.centerIn: parent
Marco Martin's avatar
Marco Martin committed
103

104 105 106 107 108 109
                flickableDirection: Flickable.HorizontalFlick
                height: windowsZoom.height * 2
                width: windowsZoom.width * 2
                interactive: windowsLayerBackground.switchMode
                contentWidth: windowsLayout.width
                contentHeight: windowsLayout.height
Marco Martin's avatar
Marco Martin committed
110

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
                MouseArea {
                    height: windowsLayer.height
                    width: windowsLayout.width
                    onClicked: {
                        compositorRoot.state = "homeScreen";
                    }
                    Row {
                        id: windowsLayout
                        anchors.centerIn: parent
                        height: windowsLayerBackground.height
                        transformOrigin: Item.Left
                        onChildrenChanged: {
                            if (children.length == 0) {
                                compositorRoot.state = "homeScreen";
                            }
Marco Martin's avatar
Marco Martin committed
126 127 128 129 130
                        }
                    }
                }
            }
        }
131
    }
132

133 134 135
    Item {
        id: panelLayer
        anchors.fill: parent
136
        visible: showPanel
137 138 139 140 141 142
        z: 3
    }

    Item {
        id: keyboardLayer
        anchors.fill: parent
Marco Martin's avatar
Marco Martin committed
143
        z: 800
144
        onVisibleChanged: {
145
            if (!visible && compositorRoot.shellWindow) {
146 147 148
                compositorRoot.shellWindow.child.takeFocus();
            }
        }
149 150
    }

151 152
    Rectangle {
        id: bottomBar
153
        z: 4
154 155 156
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
Marco Martin's avatar
Marco Martin committed
157
        height: bottomBarHeight
158
        color: Qt.rgba(0, 0, 0, 0.9)
159 160 161

        Behavior on height {
            NumberAnimation {
Marco Martin's avatar
Marco Martin committed
162
                easing.type: "InOutQuad"
163 164 165 166
                duration: units.shortDuration
            }
        }

167
        RowLayout {
168
            anchors.fill: parent
169

Marco Martin's avatar
Marco Martin committed
170 171 172 173 174
            PlasmaCore.IconItem {
                colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
                width: units.iconSizes.smallMedium
                height: width
                source: "distribute-horizontal-x"
175 176
                enabled: compositorRoot.state != "switcher" && windowsLayout.children.length > 0
                opacity: enabled ? 1 : 0.2
Marco Martin's avatar
Marco Martin committed
177 178 179 180 181 182 183 184 185 186 187 188

                Layout.alignment: Qt.AlignHCenter
                Layout.preferredWidth: units.iconSizes.medium
                Layout.preferredHeight: units.iconSizes.medium

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        compositorRoot.state = "switcher";
                    }
                }
            }
189 190 191 192
            PlasmaCore.IconItem {
                colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
                width: units.iconSizes.smallMedium
                height: width
Marco Martin's avatar
Marco Martin committed
193
                source: "go-home"
Marco Martin's avatar
Marco Martin committed
194
                enabled: compositorRoot.state != "homeScreen";
195
                opacity: enabled ? 1 : 0.2
196 197

                Layout.alignment: Qt.AlignHCenter
198 199
                Layout.preferredWidth: units.iconSizes.medium
                Layout.preferredHeight: units.iconSizes.medium
200 201 202 203

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
Marco Martin's avatar
Marco Martin committed
204
                        compositorRoot.state = "homeScreen";
205 206 207
                    }
                }
            }
208 209 210 211 212 213
            PlasmaCore.IconItem {
                colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
                width: units.iconSizes.smallMedium
                height: width
                source: "window-close"
                enabled: compositorRoot.currentWindow
214
                opacity: enabled ? 1 : 0.2
215 216 217 218 219 220 221 222 223 224 225 226 227

                Layout.alignment: Qt.AlignHCenter
                Layout.preferredWidth: units.iconSizes.medium
                Layout.preferredHeight: units.iconSizes.medium

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        compositorRoot.state = "homeScreen";
                        compositorRoot.currentWindow.close();
                    }
                }
            }
Marco Martin's avatar
Marco Martin committed
228 229
        }
    }
230

Marco Martin's avatar
Marco Martin committed
231 232 233 234 235 236 237 238 239
    MouseArea {
        id: taskSwitchEdge
        z: 1000
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        height: 8
240
        enabled: windowsLayout.children.length > 0 && compositorRoot.state != "switcher"
Marco Martin's avatar
Marco Martin committed
241 242 243 244 245
        property int oldX: 0
        onPressed: {
            oldX = mouse.x;
        }
        onPositionChanged: {
246
            compositorRoot.state = "changing";
247 248
            compositorRoot.showKeyboard = false;

Marco Martin's avatar
Marco Martin committed
249 250
            var newScale = (1-Math.abs(mouse.y)/(compositorRoot.height/2))
            if (newScale > 0.3) {
251
                windowsZoom.scale = newScale
Marco Martin's avatar
Marco Martin committed
252 253 254 255 256
            }
            windowsLayer.contentX -= (mouse.x - oldX);
            oldX = mouse.x;
        }
        onReleased: {
257
            if (windowsZoom.scale > 0.7) {
Marco Martin's avatar
Marco Martin committed
258
                compositorRoot.state = compositorRoot.currentWindow ? "application" : "homeScreen";
259 260
            } else {
                compositorRoot.state = "switcher";
261 262 263
            }
        }
    }
Marco Martin's avatar
Marco Martin committed
264 265 266 267 268 269 270 271 272

    states: [
        State {
            name: "homeScreen"
            PropertyChanges {
                target: windowsLayerBackground
                opacity: 0
            }
            PropertyChanges {
273
                target: windowsZoom
Marco Martin's avatar
Marco Martin committed
274 275 276 277 278 279 280 281 282 283
                scale: 1
            }
        },
        State {
            name: "application"
            PropertyChanges {
                target: windowsLayerBackground
                opacity: 1
            }
            PropertyChanges {
284
                target: windowsZoom
Marco Martin's avatar
Marco Martin committed
285 286 287 288
                scale: 1
            }
            PropertyChanges {
                target: windowsLayer
289
                contentX: compositorRoot.currentWindow ? compositorRoot.currentWindow.x - windowsLayerBackground.width/2 : 0
Marco Martin's avatar
Marco Martin committed
290 291 292 293 294 295 296 297
            }
        },
        State {
            name: "switcher"
            PropertyChanges {
                target: windowsLayerBackground
                opacity: 1
            }
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
            PropertyChanges {
                target: windowsZoom
                scale: 0.5
            }
            PropertyChanges {
                target: windowsLayer
                contentX: compositorRoot.currentWindow ? compositorRoot.currentWindow.x - windowsLayerBackground.width/2 : 0
            }
        },
        State {
            name: "changing"
            PropertyChanges {
                target: windowsLayerBackground
                opacity: 1
            }
Marco Martin's avatar
Marco Martin committed
313 314
            PropertyChanges {
                target: windowsLayer
315
                contentX: compositorRoot.currentWindow ? compositorRoot.currentWindow.x - windowsLayerBackground.width/2 : 0
Marco Martin's avatar
Marco Martin committed
316 317 318 319 320 321
            }
        }
    ]

    transitions: [
        Transition {
322
            to: "changing"
Marco Martin's avatar
Marco Martin committed
323 324 325 326
            SequentialAnimation {
                ScriptAction {
                    script: {
                        desktopLayer.z = 1
Marco Martin's avatar
Marco Martin committed
327
                        windowsLayerBackground.z = 800
Marco Martin's avatar
Marco Martin committed
328 329 330 331 332
                    }
                }
                PropertyAnimation {
                    target: windowsLayerBackground
                    duration: units.longDuration
Pier Luigi Fiorini's avatar
Pier Luigi Fiorini committed
333
                    easing.type: Easing.InOutQuad
Marco Martin's avatar
Marco Martin committed
334 335 336 337 338 339 340 341 342 343
                    properties: "opacity"
                }
            }
        },
        Transition {
            SequentialAnimation {
                ParallelAnimation {
                    PropertyAnimation {
                        target: windowsLayerBackground
                        duration: units.longDuration
Pier Luigi Fiorini's avatar
Pier Luigi Fiorini committed
344
                        easing.type: Easing.InOutQuad
Marco Martin's avatar
Marco Martin committed
345 346 347
                        properties: "opacity"
                    }
                    PropertyAnimation {
348
                        target: windowsZoom
Marco Martin's avatar
Marco Martin committed
349
                        duration: units.shortDuration
Pier Luigi Fiorini's avatar
Pier Luigi Fiorini committed
350
                        easing.type: Easing.InOutQuad
Marco Martin's avatar
Marco Martin committed
351 352 353 354 355
                        properties: "scale"
                    }
                    PropertyAnimation {
                        target: windowsLayer
                        duration: units.shortDuration
Pier Luigi Fiorini's avatar
Pier Luigi Fiorini committed
356
                        easing.type: Easing.InOutQuad
Marco Martin's avatar
Marco Martin committed
357 358 359 360 361 362 363 364 365 366 367
                        properties: "contentX"
                    }
                }
                ScriptAction {
                    script: {
                        if (compositorRoot.state == "homeScreen") {
                            desktopLayer.z = 2;
                            windowsLayerBackground.z = 1;
                            compositorRoot.currentWindow = null;
                        } else {
                            desktopLayer.z = 1;
Marco Martin's avatar
Marco Martin committed
368
                            windowsLayerBackground.z = 800;
369 370 371
                            if (compositorRoot.currentWindow) {
                                compositorRoot.currentWindow.child.takeFocus();
                            }
Marco Martin's avatar
Marco Martin committed
372 373 374 375 376 377
                        }
                    }
                }
            }
        }
    ]
378
}