@@ -37,8 +37,10 @@ AbstractStage {
3737 }
3838 }
3939
40+ property string mode: "staged"
41+
4042 // Used by TutorialRight
41− property bool spreadShown: spread.state == "altTab"
43+ property bool spreadShown: state == "altTab"
4244
4345 mainApp: priv.focusedAppDelegate ? priv.focusedAppDelegate.application : null
4446
@@ -57,7 +59,7 @@ AbstractStage {
5759 GlobalShortcut {
5860 id: showSpreadShortcut
5961 shortcut: Qt.MetaModifier|Qt.Key_W
60− onTriggered: spread.state = "altTab"
62+ onTriggered: state = "altTab"
6163 }
6264
6365 GlobalShortcut {
@@ -104,8 +106,8 @@ AbstractStage {
104106 Connections {
105107 target: root.topLevelSurfaceList
106108 onCountChanged: {
107− if (spread.state == "altTab") {
108− spread.cancel();
109+ if (root.state == "spread") {
110+ priv.goneToSpread = false;
109111 }
110112 }
111113 }
@@ -116,13 +118,15 @@ AbstractStage {
116118
117119 property var focusedAppDelegate: null
118120 onFocusedAppDelegateChanged: {
119− if (spread.state == "altTab") {
120− spread.state = "";
121+ if (root.state == "spread") {
122+ goneToSpread = false;
121123 }
122124 }
123125
124126 property var foregroundMaximizedAppDelegate: null // for stuff like drop shadow and focusing maximized app by clicking panel
125127
128+ property bool goneToSpread: false
129+
126130 function updateForegroundMaximizedApp() {
127131 var found = false;
128132 for (var i = 0; i < appRepeater.count && !found; i++) {
@@ -180,12 +184,12 @@ AbstractStage {
180184 target: PanelState
181185 property: "title"
182186 value: {
183− if (priv.focusedAppDelegate !== null && spread.state == "") {
184− if (priv.focusedAppDelegate.maximized)
185− return priv.focusedAppDelegate.title
186− else
187− return priv.focusedAppDelegate.appName
188− }
187+// if (priv.focusedAppDelegate !== null && spread.state == "") {
188+// if (priv.focusedAppDelegate.maximized)
189+// return priv.focusedAppDelegate.title
190+// else
191+// return priv.focusedAppDelegate.appName
192+// }
189193 return ""
190194 }
191195 when: priv.focusedAppDelegate
@@ -231,6 +235,25 @@ AbstractStage {
231235 when: !appRepeater.startingUp && root.parent
232236 }
233237
238+ states: [
239+ State {
240+ name: "spread"; when: root.altTabPressed || priv.goneToSpread
241+ },
242+ State {
243+ name: "stagedrightedge"; when: rightEdgeDragArea.dragging && root.mode == "staged"
244+ },
245+ State {
246+ name: "windowedrightedge"; when: rightEdgeDragArea.dragging && root.mode == "windowed"
247+ },
248+ State {
249+ name: "staged"; when: root.mode === "staged"
250+ },
251+ State {
252+ name: "windowed"; when: root.mode === "windowed"
253+ }
254+ ]
255+ onStateChanged: print("spread going to state:", state)
256+
234257 FocusScope {
235258 id: appContainer
236259 objectName: "appContainer"
@@ -298,6 +321,8 @@ AbstractStage {
298321
299322 readonly property var surface: model.surface
300323
324+ property real angle: 0
325+
301326 function claimFocus() {
302327 if (spread.state == "altTab") {
303328 spread.cancel();
@@ -378,7 +403,7 @@ AbstractStage {
378403 && (priv.foregroundMaximizedAppDelegate === null || priv.foregroundMaximizedAppDelegate.normalZ <= z)
379404 )
380405 || decoratedWindow.fullscreen
381− || (spread.state == "altTab" && index === spread.highlightedIndex)
406+ // || (root.state == "altTab" && index === spread.highlightedIndex)
382407
383408 function close() {
384409 model.surface.close();
@@ -440,29 +465,80 @@ AbstractStage {
440465 duration: UbuntuAnimation.SnapDuration
441466 }
442467
468+ SpreadMaths {
469+ id: spreadMaths
470+ itemIndex: index
471+ totalItems: appRepeater.count
472+ flickable: floatingFlickable
473+ }
474+ StagedRightEdgeMaths {
475+ id: stagedRightEdgeMaths
476+ itemIndex: index
477+ sceneWidth: root.width
478+ sceneHeight: root.height
479+ progress: 0
480+ targetX: spreadMaths.animatedX
481+ targetAngle: spreadMaths.animatedAngle
482+ }
483+
484+ transform: [
485+ Scale {
486+ origin.x: itemScaleOriginX
487+ origin.y: itemScaleOriginY
488+ xScale: itemScale
489+ yScale: itemScale
490+ },
491+ Rotation {
492+// origin { x: 0; y: (clippedSpreadDelegate.height - (clippedSpreadDelegate.height * itemScale / 2)) }
493+ axis { x: 0; y: 1; z: 0 }
494+ angle: appDelegate.angle
495+ }
496+ ]
497+
498+ onRequestedWidthChanged: if (index == 0) print("requestedWidth", requestedWidth)
443499 states: [
444500 State {
445− name: "fullscreen"; when: decoratedWindow.fullscreen && !appDelegate.minimized
501+ name: "spread"; when: root.state == "spread"
502+ PropertyChanges { target: appDelegate;
503+ x: spreadMaths.animatedX
504+ y: spreadMaths.animatedY
505+ z: index
506+ angle: spreadMaths.animatedAngle
507+ }
508+ PropertyChanges { target: decoratedWindow; showDecoration: false }
509+ },
510+ State {
511+ name: "stagedrightedge"; when: root.state == "stagedrightedge"
446512 PropertyChanges {
447− target: appDelegate;
448− x: 0;
449− y: -PanelState.panelHeight
450− requestedWidth: appContainer.width;
451− requestedHeight: appContainer.height;
513+ target: stagedRightEdgeMaths
514+ progress: rightEdgeDragArea.progress
515+ }
516+ PropertyChanges {
517+ target: appDelegate
518+ y: PanelState.panelHeight
519+ x: stagedRightEdgeMaths.animatedX
520+ requestedWidth: stagedRightEdgeMaths.animatedWidth
521+ requestedHeight: stagedRightEdgeMaths.animatedHeight
522+ angle: stagedRightEdgeMaths.animatedAngle
523+ z: index
452524 }
525+ PropertyChanges { target: decoratedWindow; showDecoration: false }
453526 },
454527 State {
455− name: "normal";
456− when: !appDelegate.maximized && !appDelegate.minimized
457− && !appDelegate.maximizedLeft && !appDelegate.maximizedRight
528+ name: "staged"; when: root.state == "staged"
458529 PropertyChanges {
459− target: appDelegate;
460− visuallyMinimized: false;
461− visuallyMaximized: false
530+ target: appDelegate
531+ x: 0; y: 0
532+ visuallyMaximized: true
533+ }
534+ PropertyChanges {
535+ target: decoratedWindow
536+ requestedWidth: appContainer.width - root.leftMargin;
537+ requestedHeight: appContainer.height;
462538 }
463539 },
464540 State {
465− name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized
541+ name: "maximized"; when: root.state === "windowed" && appDelegate.maximized && !appDelegate.minimized
466542 PropertyChanges {
467543 target: appDelegate;
468544 x: root.leftMargin;
@@ -476,6 +552,26 @@ AbstractStage {
476552 requestedHeight: appContainer.height;
477553 }
478554 },
555+ State {
556+ name: "fullscreen"; when: decoratedWindow.fullscreen && !appDelegate.minimized
557+ PropertyChanges {
558+ target: appDelegate;
559+ x: 0;
560+ y: -PanelState.panelHeight
561+ requestedWidth: appContainer.width;
562+ requestedHeight: appContainer.height;
563+ }
564+ },
565+ State {
566+ name: "normal";
567+ when: !appDelegate.maximized && !appDelegate.minimized
568+ && !appDelegate.maximizedLeft && !appDelegate.maximizedRight
569+ PropertyChanges {
570+ target: appDelegate;
571+ visuallyMinimized: false;
572+ visuallyMaximized: false
573+ }
574+ },
479575 State {
480576 name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized
481577 PropertyChanges {
@@ -513,6 +609,7 @@ AbstractStage {
513609 visuallyMaximized: false
514610 }
515611 }
612+
516613 ]
517614 transitions: [
518615 Transition {
@@ -543,7 +640,7 @@ AbstractStage {
543640 }
544641 },
545642 Transition {
546− to: "*" //maximized and fullscreen
643+ to: "maximized,fullscreen" //maximized and fullscreen
547644 enabled: appDelegate.animationsEnabled
548645 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
549646 SequentialAnimation {
@@ -553,16 +650,25 @@ AbstractStage {
553650 }
554651 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
555652 }
653+ },
654+ Transition {
655+ to: "spread"
656+ PropertyAnimation { target: appDelegate; properties: "x,y,width,height"; duration: UbuntuAnimation.FastDuration }
657+ },
658+ Transition {
659+ to: "staged";
660+ PropertyAnimation { target: appDelegate; properties: "x,y,width,height"; duration: UbuntuAnimation.FastDuration }
556661 }
662+
557663 ]
558664
559− Binding {
560− id: previewBinding
561− target: appDelegate
562− property: "z"
563− value: topLevelSurfaceList.count + 1
564− when: index == spread.highlightedIndex && spread.ready
565− }
665+// Binding {
666+// id: previewBinding
667+// target: appDelegate
668+// property: "z"
669+// value: topLevelSurfaceList.count + 1
670+// when: index == spread.highlightedIndex
671+// }
566672
567673 WindowResizeArea {
568674 id: resizeArea
@@ -607,6 +713,7 @@ AbstractStage {
607713 surface: model.surface
608714 active: appDelegate.focus
609715 focus: true
716+ showDecoration: true
610717
611718 requestedWidth: appDelegate.requestedWidth
612719 requestedHeight: appDelegate.requestedHeight
@@ -650,23 +757,91 @@ AbstractStage {
650757 }
651758 }
652759
760+ FloatingFlickable {
761+ id: floatingFlickable
762+ anchors.fill: parent
763+
764+ property int minContentWidth: 6 * Math.min(height / 4, width / 5)
765+ contentWidth: Math.max(6, appRepeater.count) * Math.min(height / 4, width / 5)
766+
767+ }
768+
653769 DirectionalDragArea {
770+ id: rightEdgeDragArea
654771 direction: Direction.Leftwards
655772 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
656− width: units.gu(1)
657− onDraggingChanged: { if (dragging) { spread.show(); } }
658− }
773+ width: root.dragAreaWidth
774+
775+ property var gesturePoints: new Array()
776+
777+ property real progress: -touchX / root.width
778+ onProgressChanged: print("dda progress", progress, root.width, touchX, root.width + touchX)
779+
780+ Rectangle { color: "blue"; anchors.fill: parent }
781+ onTouchXChanged: {
782+ if (dragging) {
783+ // Gesture recognized. Let's move the spreadView with the finger
784+// var dragX = Math.min(touchX + width, width); // Prevent dragging rightwards
785+// dragX = -dragX + spreadDragArea.width - spreadView.shift;
786+// // Don't allow dragging further than the animation crossing with phase2's animation
787+// var maxMovement = spreadView.width * spreadView.positionMarker4 - spreadView.shift;
788+
789+// spreadView.contentX = Math.min(dragX, maxMovement);
790+ } else {
791+// // Initial touch. Let's reset the spreadView to the starting position.
792+// spreadView.phase = 0;
793+// spreadView.contentX = -spreadView.shift;
794+ }
659795
660− DesktopSpread {
661− id: spread
662− objectName: "spread"
663− anchors.fill: appContainer
664− workspace: appContainer
665− focus: state == "altTab"
666− altTabPressed: root.altTabPressed
796+ gesturePoints.push(touchX);
797+ }
667798
668− onPlayFocusAnimation: {
669− appRepeater.itemAt(index).playFocusAnimation();
799+ onDraggingChanged: {
800+ print("dda dragging changed", dragging)
801+ if (dragging) {
802+ // A potential edge-drag gesture has started. Start recording it
803+ gesturePoints = [];
804+ } else {
805+ if (gesturePoints[gesturePoints.length - 1] < -root.width / 2) {
806+ priv.goneToSpread = true;
807+ }
808+
809+// // Ok. The user released. Find out if it was a one-way movement.
810+// var oneWayFlick = true;
811+// var smallestX = spreadDragArea.width;
812+// for (var i = 0; i < gesturePoints.length; i++) {
813+// if (gesturePoints[i] >= smallestX) {
814+// oneWayFlick = false;
815+// break;
816+// }
817+// smallestX = gesturePoints[i];
818+// }
819+// gesturePoints = [];
820+
821+// if (oneWayFlick && spreadView.shiftedContentX > units.gu(2) &&
822+// spreadView.shiftedContentX < spreadView.positionMarker1 * spreadView.width) {
823+// // If it was a short one-way movement, do the Alt+Tab switch
824+// // no matter if we didn't cross positionMarker1 yet.
825+// spreadView.snapTo(1);
826+// } else if (!dragging) {
827+// // otherwise snap to the closest snap position we can find
828+// // (might be back to start, to app 1 or to spread)
829+// spreadView.snap();
830+// }
831+ }
670832 }
671833 }
834+
835+// DesktopSpread {
836+// id: spread
837+// objectName: "spread"
838+// anchors.fill: appContainer
839+// workspace: appContainer
840+// focus: state == "altTab"
841+// altTabPressed: root.altTabPressed
842+
843+// onPlayFocusAnimation: {
844+// appRepeater.itemAt(index).playFocusAnimation();
845+// }
846+// }
672847}