@@ -18,39 +18,41 @@
19import QtQuick 2.0
19import QtQuick 2.0
20import Mir.Application 0.1
20import Mir.Application 0.1
21−import Ubuntu.Components 1.0
21+import Ubuntu.Components 1.1
22import "../Components"
22import "../Components"
28 property bool interactive: true
27 property bool interactive: true
29− property real maximizedAppTopMargin
30− property bool isFullscreen: surface !== null && surface.anchors.topMargin == 0
31 property bool dropShadow: true
28 property bool dropShadow: true
29+ property real maximizedAppTopMargin
33− // FIXME: This really should be invisible to QML code.
31+ readonly property bool isFullscreen: surface !== null && surfaceContainer.surface.anchors.topMargin == 0
34− // e.g. Create a SurfaceItem {} in C++ which we just use without any imperative hacks.
35− readonly property var surface: model.surface
36− onSurfaceChanged: { print("SURFACE!!", model.surface)
38− if (!priv.appHasCreatedASurface) {
39− surface.visible = false; // hide until splash screen removed
40− priv.appHasCreatedASurface = true;
43− surface.parent = root;
33+ signal clicked()
44− surface.anchors.fill = root;
34+ signal closed()
45− priv.checkFullscreen(surface);
51− id: priv
37+ id: surfaceContainer
39+ readonly property var surface: model.surface
52 property bool appHasCreatedASurface: false
40 property bool appHasCreatedASurface: false
42+ onSurfaceChanged: { print("SURFACE!!", model.surface)
44+ if (!appHasCreatedASurface) {
45+ surface.visible = false; // hide until splash screen removed
46+ appHasCreatedASurface = true;
49+ surface.parent = surfaceContainer;
50+ surface.anchors.fill = surfaceContainer;
51+ checkFullscreen(surface);
54 function checkFullscreen(surface) {
56 function checkFullscreen(surface) {
55 if (surface.state === MirSurfaceItem.Fullscreen) {
57 if (surface.state === MirSurfaceItem.Fullscreen) {
56 surface.anchors.topMargin = 0;
58 surface.anchors.topMargin = 0;
@@ -63,43 +65,58 @@ Item {
63 surface.visible = true;
65 surface.visible = true;
64 splashLoader.source = "";
66 splashLoader.source = "";
68− Timer { //FIXME - need to delay removing splash screen to allow surface resize to complete
69+ Binding {
69− id: surfaceRevealDelay
70+ target: surface
70− interval: 100
71+ property: "enabled"
71− onTriggered: priv.revealSurface()
72+ value: root.interactive
74− Binding {
75+ Timer { //FIXME - need to delay removing splash screen to allow surface resize to complete
75− target: surface
76+ id: surfaceRevealDelay
76− property: "enabled"
77+ interval: 100
77− value: root.interactive
78+ onTriggered: surfaceContainer.revealSurface()
80− Connections {
81+ Connections {
81− target: surface
82+ target: surface
82− onStateChanged: priv.checkFullscreen(surface);
83+ onStateChanged: checkFullscreen(surface);
89+ anchors.margins: -units.gu(2)
90+ source: "graphics/dropshadow.png"
91+ border { left: 50; right: 50; top: 50; bottom: 50 }
92+ opacity: root.dropShadow ? .4 : 0
93+ Behavior on opacity { UbuntuNumberAnimation {} }
96+ transform: Translate {
85 StateGroup {
102 StateGroup {
86 id: appSurfaceState
103 id: appSurfaceState
87 states: [
104 states: [
89 name: "noSurfaceYet"
106 name: "noSurfaceYet"
90− when: !priv.appHasCreatedASurface
107+ when: !surfaceContainer.appHasCreatedASurface
91 StateChangeScript {
108 StateChangeScript {
92− script: {splashLoader.setSource("Splash.qml", { "name": model.name, "image": model.icon }); }
109+ script: { splashLoader.setSource("Splash.qml", { "name": model.name, "image": model.icon }); }
96 name: "hasSurface"
113 name: "hasSurface"
97− when: priv.appHasCreatedASurface && (root.surface !== null)
114+ when: surfaceContainer.appHasCreatedASurface && (surfaceContainer.surface !== null)
98 StateChangeScript { script: { surfaceRevealDelay.start(); } }
115 StateChangeScript { script: { surfaceRevealDelay.start(); } }
101 name: "surfaceLostButAppStillAlive"
118 name: "surfaceLostButAppStillAlive"
102− when: priv.appHasCreatedASurface && (root.surface === null)
119+ when: surfaceContainer.appHasCreatedASurface && (surfaceContainer.surface === null)
103 // TODO - use app snapshot
120 // TODO - use app snapshot
@@ -108,25 +125,76 @@ Item {
110 id: splashLoader
127 id: splashLoader
111− anchors.fill: parent
128+ anchors.fill: surfaceContainer
116− anchors.fill: surface
117− anchors.margins: -units.gu(2)
118− source: "graphics/dropshadow.png"
119− border { left: 50; right: 50; top: 50; bottom: 50 }
120− opacity: root.dropShadow ? .4 : 0
121− Behavior on opacity { UbuntuNumberAnimation {} }
124− MouseArea {
131+ DraggingArea {
125 anchors.fill: parent
133 anchors.fill: parent
127 enabled: !root.interactive
134 enabled: !root.interactive
136+ property bool moving: false
137+ property real distance: 0
140+ spreadView.draggedIndex = moving ? index : -1
143+ onDragValueChanged: {
144+ moving = moving || Math.abs(dragValue) > units.gu(1)
145+ if (moving && dragging) {
146+ distance = dragValue;
129− root.clicked()
152+ root.clicked();
156+ if ((dragVelocity < -600 && distance < -units.gu(4)) || distance < -root.height / 2) {
157+ animation.animate("up")
158+ } else if ((dragVelocity > 600 && distance > units.gu(4)) || distance > root.height / 2) {
159+ animation.animate("down")
161+ animation.animate("center")
165+ UbuntuNumberAnimation {
168+ property: "distance"
169+ property bool requestClose: false
171+ function animate(direction) {
172+ animation.from = dragArea.distance
173+ switch (direction) {
175+ animation.to = -root.height
176+ requestClose = true;
179+ animation.to = root.height
180+ requestClose = true;
190+ dragArea.moving = false;
191+ dragArea.distance = 0;