@@ -17,45 +17,28 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20−import Unity.Application 0.1
20+import Mir.Application 0.1
21import Utils 0.1
21import Utils 0.1
22import "../Components"
22import "../Components"
27 // Controls to be set from outside
28 // Controls to be set from outside
28− property bool shown: false
29− property bool moving: false
30 property int dragAreaWidth
29 property int dragAreaWidth
31+ // FIXME: Should be registerd singleton type QAbstractItemModel.
32+ property var surfaces
32 // State information propagated to the outside
34 // State information propagated to the outside
33− readonly property bool painting: mainScreenshotImage.visible || fadeInScreenshotImage.visible || appSplash.visible || spreadView.visible
34 property bool fullscreen: priv.focusedApplication ? priv.focusedApplication.fullscreen : false
35 property bool fullscreen: priv.focusedApplication ? priv.focusedApplication.fullscreen : false
35 property bool locked: spreadView.visible
36 property bool locked: spreadView.visible
37− // Not used for PhoneStage, only useful for SideStage and similar
38− property bool overlayMode: false
39− property int overlayWidth: 0
41 function select(appId) {
38 function select(appId) {
42 spreadView.snapTo(priv.indexOf(appId))
39 spreadView.snapTo(priv.indexOf(appId))
47− if (ApplicationManager.focusedApplicationId) {
48− priv.requestNewScreenshot();
50− mainScreenshotImage.anchors.leftMargin = 0;
51− mainScreenshotImage.source = ApplicationManager.get(0).screenshot;
52− mainScreenshotImage.visible = true;
55− mainScreenshotImage.visible = false;
59 Connections {
42 Connections {
60 target: ApplicationManager
43 target: ApplicationManager
@@ -74,7 +57,6 @@ Item {
75 var application = priv.focusedApplication;
58 var application = priv.focusedApplication;
76 root.fullscreen = application.fullscreen;
59 root.fullscreen = application.fullscreen;
77− mainScreenshotImage.source = application.screenshot;
80 spreadView.selectedIndex = -1;
62 spreadView.selectedIndex = -1;
@@ -84,29 +66,7 @@ Item {
86 onApplicationAdded: {
68 onApplicationAdded: {
87− if (!priv.focusedApplication) {
88− mainScreenshotImage.source = "";
89− mainScreenshotImage.visible = false;
90− priv.applicationStarting = true;
92− mainScreenshotImage.source = "";
93− priv.newFocusedAppId = appId;
94− priv.secondApplicationStarting = true;
95− priv.requestNewScreenshot();
98− if (spreadView.visible) {
99− spreadView.snapTo(0);
69+ spreadView.snapTo(0);
103− onApplicationRemoved: {
104− if (ApplicationManager.count == 0) {
105− mainScreenshotImage.source = ""
106− mainScreenshotImage.visible = false;
108− mainScreenshotImage.source = ApplicationManager.get(0).screenshot;
@@ -115,31 +75,12 @@ Item {
116 property string focusedAppId: ApplicationManager.focusedApplicationId
76 property string focusedAppId: ApplicationManager.focusedApplicationId
117 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
77 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
118− property url focusedScreenshot: focusedApplication ? focusedApplication.screenshot : ""
120− property bool waitingForScreenshot: false
122 property bool applicationStarting: false
79 property bool applicationStarting: false
123 property bool secondApplicationStarting: false
80 property bool secondApplicationStarting: false
125 property string newFocusedAppId
82 property string newFocusedAppId
127− onFocusedScreenshotChanged: {
128− if (root.moving && priv.waitingForScreenshot) {
129− mainScreenshotImage.anchors.leftMargin = 0;
130− mainScreenshotImage.source = priv.focusedScreenshot
131− mainScreenshotImage.visible = true;
132− } else if (priv.secondApplicationStarting && priv.waitingForScreenshot) {
133− applicationSwitchingAnimation.start();
135− waitingForScreenshot = false;
138− function requestNewScreenshot() {
139− waitingForScreenshot = true;
140− ApplicationManager.updateScreenshot(focusedAppId);
143 function switchToApp(appId) {
84 function switchToApp(appId) {
144 if (priv.focusedAppId) {
85 if (priv.focusedAppId) {
145 priv.newFocusedAppId = appId;
86 priv.newFocusedAppId = appId;
@@ -147,6 +88,8 @@ Item {
147 applicationSwitchingAnimation.start();
88 applicationSwitchingAnimation.start();
149 ApplicationManager.focusApplication(appId);
90 ApplicationManager.focusApplication(appId);
91+ // TODO: Should happen behind the schenes
92+ surfaces.move(surfaces.getIndexOfSurfaceWithAppId(appId), 0);
@@ -161,155 +104,6 @@ Item {
164− // FIXME: the signal connections seems to get lost.
166− target: priv.focusedApplication
167− onScreenshotChanged: priv.focusedScreenshot = priv.focusedApplication.screenshot
171− property: "fullscreen"
172− value: priv.focusedApplication ? priv.focusedApplication.fullscreen : false
177− // FIXME: We really need to show something meaningful in the app surface instead of guessing
178− // when it might be ready
182− priv.applicationStarting = false;
183− priv.secondApplicationStarting = false;
187− SequentialAnimation {
188− id: applicationSwitchingAnimation
190− PropertyAction { target: mainScreenshotImage; property: "anchors.leftMargin"; value: 0 }
191− PropertyAction { target: mainScreenshotImage; property: "source"; value: priv.focusedScreenshot }
192− PropertyAction { targets: [mainScreenshotImage, fadeInScreenshotImage]; property: "visible"; value: true }
193− PropertyAction { target: fadeInScreenshotImage; property: "source"; value: {
194− var newFocusedApp = ApplicationManager.findApplication(priv.newFocusedAppId);
195− return newFocusedApp ? newFocusedApp.screenshot : "" }
197− PropertyAction { target: fadeInScreenshotImage; property: "opacity"; value: 0 }
198− PropertyAction { target: fadeInScreenshotImage; property: "scale"; value: .8 }
201− // The actual animation
203− UbuntuNumberAnimation { target: mainScreenshotImage; property: "anchors.leftMargin"; to: root.width; duration: UbuntuAnimation.SlowDuration }
204− UbuntuNumberAnimation { target: fadeInScreenshotImage; properties: "opacity,scale"; to: 1; duration: UbuntuAnimation.SlowDuration }
208− ScriptAction { script: ApplicationManager.focusApplication(priv.newFocusedAppId); }
209− PropertyAction { target: fadeInScreenshotImage; property: "visible"; value: false }
210− PropertyAction { target: mainScreenshotImage; property: "visible"; value: false }
213− // FIXME: Drop this and make the imageprovider show a splashscreen instead
216− anchors.fill: parent
218− visible: priv.secondApplicationStarting
221− id: fadeInScreenshotImage
222− anchors { left: parent.left; bottom: parent.bottom }
230− anchors.fill: parent
232− visible: priv.applicationStarting
235− id: mainScreenshotImage
236− anchors { left: parent.left; bottom: parent.bottom }
243− direction: Direction.Leftwards
244− enabled: ApplicationManager.count > 1 && spreadView.phase != 2
246− anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
247− width: root.dragAreaWidth
249− // Sitting at the right edge of the screen, this EdgeDragArea directly controls the spreadView when
250− // attachedToView is true. When the finger movement passes positionMarker3 we detach it from the
251− // spreadView and make the spreadView snap to positionMarker4.
252− property bool attachedToView: true
254− property var gesturePoints: new Array()
257− if (!dragging && !priv.waitingForScreenshot) {
258− // Initial touch. Let's update the screenshot and reset the spreadView to the starting position.
259− priv.requestNewScreenshot();
260− spreadView.phase = 0;
261− spreadView.contentX = -spreadView.shift;
263− if (dragging && attachedToView) {
264− // Gesture recognized. Let's move the spreadView with the finger
265− spreadView.contentX = -touchX - spreadView.shift;
267− if (attachedToView && spreadView.shiftedContentX >= spreadView.width * spreadView.positionMarker3) {
268− // We passed positionMarker3. Detach from spreadView and snap it.
269− attachedToView = false;
272− gesturePoints.push(touchX);
276− if (status == DirectionalDragArea.Recognized) {
277− attachedToView = true;
281− onDraggingChanged: {
283− // Gesture recognized. Start recording this gesture
288− // Ok. The user released. Find out if it was a one-way movement.
289− var oneWayFlick = true;
290− var smallestX = spreadDragArea.width;
291− for (var i = 0; i < gesturePoints.length; i++) {
292− if (gesturePoints[i] >= smallestX) {
293− oneWayFlick = false;
296− smallestX = gesturePoints[i];
300− if (oneWayFlick && spreadView.shiftedContentX > units.gu(2) &&
301− spreadView.shiftedContentX < spreadView.positionMarker1 * spreadView.width) {
302− // If it was a short one-way movement, do the Alt+Tab switch
303− // no matter if we didn't cross positionMarker1 yet.
304− spreadView.snapTo(1);
305− } else if (!dragging && attachedToView) {
306− // otherwise snap to the closest snap position we can find
307− // (might be back to start, to app 1 or to spread)
313 Rectangle {
107 Rectangle {
314 id: coverFlipBackground
108 id: coverFlipBackground
315 anchors.fill: parent
109 anchors.fill: parent
@@ -317,16 +111,13 @@ Item {
317 visible: spreadView.visible
111 visible: spreadView.visible
322− blockInput: spreadView.visible
325 Flickable {
115 Flickable {
326 id: spreadView
116 id: spreadView
327 objectName: "spreadView"
117 objectName: "spreadView"
328 anchors.fill: parent
118 anchors.fill: parent
329− visible: spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1 || snapAnimation.running
119+// visible: spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1 || snapAnimation.running
120+ interactive: spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1 || snapAnimation.running
330 contentWidth: spreadRow.width - shift
121 contentWidth: spreadRow.width - shift
331 contentX: -shift
122 contentX: -shift
@@ -414,6 +205,10 @@ Item {
414 script: {
205 script: {
415 if (spreadView.selectedIndex >= 0) {
206 if (spreadView.selectedIndex >= 0) {
416 ApplicationManager.focusApplication(ApplicationManager.get(spreadView.selectedIndex).appId);
207 ApplicationManager.focusApplication(ApplicationManager.get(spreadView.selectedIndex).appId);
209+ // TODO: Should happen behind the schenes
210+ surfaces.move(spreadView.selectedIndex, 0);
417 spreadView.selectedIndex = -1
212 spreadView.selectedIndex = -1
418 spreadView.phase = 0;
213 spreadView.phase = 0;
419 spreadView.contentX = -spreadView.shift;
214 spreadView.contentX = -spreadView.shift;
@@ -433,7 +228,7 @@ Item {
434 Repeater {
229 Repeater {
435 id: spreadRepeater
230 id: spreadRepeater
436− model: ApplicationManager
231+ model: root.surfaces
437 delegate: TransformedSpreadDelegate {
232 delegate: TransformedSpreadDelegate {
438 id: appDelegate
233 id: appDelegate
439 objectName: "appDelegate" + index
234 objectName: "appDelegate" + index
@@ -447,6 +242,8 @@ Item {
447 height: spreadView.height
242 height: spreadView.height
448 selected: spreadView.selectedIndex == index
243 selected: spreadView.selectedIndex == index
449 otherSelected: spreadView.selectedIndex >= 0 && !selected
244 otherSelected: spreadView.selectedIndex >= 0 && !selected
245+ surface: model.surface
246+ interactive: !spreadView.interactive
452 x: index == 0 ? 0 : spreadView.width + (index - 1) * spreadView.tileDistance
249 x: index == 0 ? 0 : spreadView.width + (index - 1) * spreadView.tileDistance
@@ -496,4 +293,76 @@ Item {
299+ direction: Direction.Leftwards
300+ enabled: ApplicationManager.count > 1 && spreadView.phase != 2
302+ anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
303+ width: root.dragAreaWidth
305+ // Sitting at the right edge of the screen, this EdgeDragArea directly controls the spreadView when
306+ // attachedToView is true. When the finger movement passes positionMarker3 we detach it from the
307+ // spreadView and make the spreadView snap to positionMarker4.
308+ property bool attachedToView: true
310+ property var gesturePoints: new Array()
314+ // Initial touch. Let's reset the spreadView to the starting position.
315+ spreadView.phase = 0;
316+ spreadView.contentX = -spreadView.shift;
318+ if (dragging && attachedToView) {
319+ // Gesture recognized. Let's move the spreadView with the finger
320+ spreadView.contentX = -touchX - spreadView.shift;
322+ if (attachedToView && spreadView.shiftedContentX >= spreadView.width * spreadView.positionMarker3) {
323+ // We passed positionMarker3. Detach from spreadView and snap it.
324+ attachedToView = false;
327+ gesturePoints.push(touchX);
331+ if (status == DirectionalDragArea.Recognized) {
332+ attachedToView = true;
336+ onDraggingChanged: {
338+ // Gesture recognized. Start recording this gesture
343+ // Ok. The user released. Find out if it was a one-way movement.
344+ var oneWayFlick = true;
345+ var smallestX = spreadDragArea.width;
346+ for (var i = 0; i < gesturePoints.length; i++) {
347+ if (gesturePoints[i] >= smallestX) {
348+ oneWayFlick = false;
351+ smallestX = gesturePoints[i];
355+ if (oneWayFlick && spreadView.shiftedContentX > units.gu(2) &&
356+ spreadView.shiftedContentX < spreadView.positionMarker1 * spreadView.width) {
357+ // If it was a short one-way movement, do the Alt+Tab switch
358+ // no matter if we didn't cross positionMarker1 yet.
359+ spreadView.snapTo(1);
360+ } else if (!dragging && attachedToView) {
361+ // otherwise snap to the closest snap position we can find
362+ // (might be back to start, to app 1 or to spread)