on xenial help sign in
make spread reversible Fixes: #1355284, #1368668, #1368677
16b7d9aMichael Zanetti
qml/Stages/PhoneStage.qml+17−33
@@ -145,16 +145,16 @@ Rectangle {
145
145
146 // Those markers mark the various positions in the spread (ratio to screen width from right to left):
146 // Those markers mark the various positions in the spread (ratio to screen width from right to left):
147 // 0 - 1: following finger, snap back to the beginning on release
147 // 0 - 1: following finger, snap back to the beginning on release
148− property real positionMarker1: 0.3
148+ property real positionMarker1: 0.2
149 // 1 - 2: curved snapping movement, snap to app 1 on release
149 // 1 - 2: curved snapping movement, snap to app 1 on release
150− property real positionMarker2: 0.45
150+ property real positionMarker2: 0.3
151 // 2 - 3: movement follows finger, snaps back to app 1 on release
151 // 2 - 3: movement follows finger, snaps back to app 1 on release
152− property real positionMarker3: 0.6
152+ property real positionMarker3: 0.35
153 // passing 3, we detach movement from the finger and snap to 4
153 // passing 3, we detach movement from the finger and snap to 4
154 property real positionMarker4: 0.9
154 property real positionMarker4: 0.9
155
155
156 // This is where the first app snaps to when bringing it in from the right edge.
156 // This is where the first app snaps to when bringing it in from the right edge.
157− property real snapPosition: 0.75
157+ property real snapPosition: 0.7
158
158
159 // Phase of the animation:
159 // Phase of the animation:
160 // 0: Starting from right edge, a new app (index 1) comes in from the right
160 // 0: Starting from right edge, a new app (index 1) comes in from the right
@@ -178,7 +178,7 @@ Rectangle {
178 case 1:
178 case 1:
179 if (shiftedContentX < width * positionMarker2) {
179 if (shiftedContentX < width * positionMarker2) {
180 phase = 0;
180 phase = 0;
181− } else if (shiftedContentX >= width * positionMarker4) {
181+ } else if (shiftedContentX >= width * positionMarker4 && !spreadDragArea.dragging) {
182 phase = 2;
182 phase = 2;
183 }
183 }
184 break;
184 break;
@@ -270,6 +270,7 @@ Rectangle {
270
270
271 Repeater {
271 Repeater {
272 id: spreadRepeater
272 id: spreadRepeater
273+ objectName: "spreadRepeater"
273 model: ApplicationManager
274 model: ApplicationManager
274 delegate: TransformedSpreadDelegate {
275 delegate: TransformedSpreadDelegate {
275 id: appDelegate
276 id: appDelegate
@@ -367,8 +368,9 @@ Rectangle {
367 if (spreadView.phase == 0 && index < 2) {
368 if (spreadView.phase == 0 && index < 2) {
368 if (progress < spreadView.positionMarker1) {
369 if (progress < spreadView.positionMarker1) {
369 return progress;
370 return progress;
370− } else if (progress < spreadView.positionMarker1 + snappingCurve.period){
371+ } else if (progress < spreadView.positionMarker1 + 0.05){
371− return spreadView.positionMarker1 + snappingCurve.value * 3;
372+ // p : 0.05 = x : pm2
373+ return spreadView.positionMarker1 + (progress - spreadView.positionMarker1) * (spreadView.positionMarker2 - spreadView.positionMarker1) / 0.05
372 } else {
374 } else {
373 return spreadView.positionMarker2;
375 return spreadView.positionMarker2;
374 }
376 }
@@ -380,13 +382,6 @@ Rectangle {
380 visible: (progress >= 0 && progress < 1.7) ||
382 visible: (progress >= 0 && progress < 1.7) ||
381 (isDash && priv.focusedAppDelegate.x !== 0)
383 (isDash && priv.focusedAppDelegate.x !== 0)
382
384
383− EasingCurve {
384− id: snappingCurve
385− type: EasingCurve.Linear
386− period: 0.05
387− progress: appDelegate.progress - spreadView.positionMarker1
388− }
389−
390 Binding {
385 Binding {
391 target: appDelegate
386 target: appDelegate
392 property: "orientation"
387 property: "orientation"
@@ -425,16 +420,11 @@ Rectangle {
425 id: spreadDragArea
420 id: spreadDragArea
426 objectName: "spreadDragArea"
421 objectName: "spreadDragArea"
427 direction: Direction.Leftwards
422 direction: Direction.Leftwards
428− enabled: spreadView.phase != 2 && root.spreadEnabled
423+ enabled: (spreadView.phase != 2 && root.spreadEnabled) || dragging
429
424
430 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
425 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
431 width: root.dragAreaWidth
426 width: root.dragAreaWidth
432
427
433− // Sitting at the right edge of the screen, this EdgeDragArea directly controls the spreadView when
434− // attachedToView is true. When the finger movement passes positionMarker3 we detach it from the
435− // spreadView and make the spreadView snap to positionMarker4.
436− property bool attachedToView: true
437−
438 property var gesturePoints: new Array()
428 property var gesturePoints: new Array()
439
429
440 onTouchXChanged: {
430 onTouchXChanged: {
@@ -443,15 +433,13 @@ Rectangle {
443 spreadView.phase = 0;
433 spreadView.phase = 0;
444 spreadView.contentX = -spreadView.shift;
434 spreadView.contentX = -spreadView.shift;
445 }
435 }
446− if (dragging && status == DirectionalDragArea.Recognized && attachedToView) {
436+ if (dragging && status == DirectionalDragArea.Recognized) {
447 // Gesture recognized. Let's move the spreadView with the finger
437 // Gesture recognized. Let's move the spreadView with the finger
448− var finalX = Math.min(touchX + width, width);
438+ var dragX = Math.min(touchX + width, width); // Prevent dragging rightwards
449− spreadView.contentX = -finalX + spreadDragArea.width - spreadView.shift;
439+ dragX = -dragX + spreadDragArea.width - spreadView.shift;
450− }
440+ // Don't allow dragging further than the animation crossing with phase2's animation
451− if (attachedToView && spreadView.shiftedContentX >= spreadView.width * spreadView.positionMarker3) {
441+ var maxMovement = spreadView.width * spreadView.positionMarker4 - spreadView.shift;
452− // We passed positionMarker3. Detach from spreadView and snap it.
442+ spreadView.contentX = Math.min(dragX, maxMovement);
453− attachedToView = false;
454− spreadView.snap();
455 }
443 }
456 gesturePoints.push(touchX);
444 gesturePoints.push(touchX);
457 }
445 }
@@ -462,10 +450,6 @@ Rectangle {
462 onStatusChanged: {
450 onStatusChanged: {
463 previousStatus = currentStatus;
451 previousStatus = currentStatus;
464 currentStatus = status;
452 currentStatus = status;
465−
466− if (status == DirectionalDragArea.Recognized) {
467− attachedToView = true;
468− }
469 }
453 }
470
454
471 onDraggingChanged: {
455 onDraggingChanged: {
@@ -493,7 +477,7 @@ Rectangle {
493 // If it was a short one-way movement, do the Alt+Tab switch
477 // If it was a short one-way movement, do the Alt+Tab switch
494 // no matter if we didn't cross positionMarker1 yet.
478 // no matter if we didn't cross positionMarker1 yet.
495 spreadView.snapTo(1);
479 spreadView.snapTo(1);
496− } else if (!dragging && attachedToView) {
480+ } else if (!dragging) {
497 // otherwise snap to the closest snap position we can find
481 // otherwise snap to the closest snap position we can find
498 // (might be back to start, to app 1 or to spread)
482 // (might be back to start, to app 1 or to spread)
499 spreadView.snap();
483 spreadView.snap();
qml/Stages/TabletStage.qml+5−14
@@ -590,7 +590,6 @@ Rectangle {
590 width: root.dragAreaWidth
590 width: root.dragAreaWidth
591 direction: Direction.Leftwards
591 direction: Direction.Leftwards
592
592
593− property bool attachedToView: false
594 property var gesturePoints: new Array()
593 property var gesturePoints: new Array()
595
594
596 onTouchXChanged: {
595 onTouchXChanged: {
@@ -599,22 +598,14 @@ Rectangle {
599 spreadView.contentX = -spreadView.shift;
598 spreadView.contentX = -spreadView.shift;
600 }
599 }
601
600
602− if (dragging && attachedToView) {
601+ if (dragging) {
603− spreadView.contentX = -touchX + spreadDragArea.width - spreadView.shift;
602+ var dragX = -touchX + spreadDragArea.width - spreadView.shift;
604− if (spreadView.shiftedContentX > spreadView.phase0Width + spreadView.phase1Width / 2) {
603+ var maxDrag = spreadView.width * spreadView.positionMarker4 - spreadView.shift;
605− attachedToView = false;
604+ spreadView.contentX = Math.min(dragX, maxDrag);
606− spreadView.snap();
607− }
608 }
605 }
609 gesturePoints.push(touchX);
606 gesturePoints.push(touchX);
610 }
607 }
611
608
612− onStatusChanged: {
613− if (status == DirectionalDragArea.Recognized) {
614− attachedToView = true;
615− }
616− }
617−
618 onDraggingChanged: {
609 onDraggingChanged: {
619 if (dragging) {
610 if (dragging) {
620 // Gesture recognized. Start recording this gesture
611 // Gesture recognized. Start recording this gesture
@@ -630,7 +621,7 @@ Rectangle {
630 // If it was a short one-way movement, do the Alt+Tab switch
621 // If it was a short one-way movement, do the Alt+Tab switch
631 // no matter if we didn't cross positionMarker1 yet.
622 // no matter if we didn't cross positionMarker1 yet.
632 spreadView.snapTo(spreadView.nextInStack);
623 spreadView.snapTo(spreadView.nextInStack);
633− } else if (!dragging && attachedToView) {
624+ } else if (!dragging) {
634 if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker1) {
625 if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker1) {
635 spreadView.snap();
626 spreadView.snap();
636 } else if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker2) {
627 } else if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker2) {
tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py+1−1
@@ -47,7 +47,7 @@ class ApplicationLifecycleTests(tests.ApplicationLifeCycleTestCase):
47 height = self.main_window.height
47 height = self.main_window.height
48 start_x = width
48 start_x = width
49 start_y = int(height/2)
49 start_y = int(height/2)
50− end_x = int(width/2)
50+ end_x = int(width*3/4)
51 end_y = start_y
51 end_y = start_y
52
52
53 logger.info("Swiping screen from the right edge")
53 logger.info("Swiping screen from the right edge")
tests/qmltests/Stages/tst_PhoneStage.qml+8−3
@@ -128,17 +128,20 @@ Item {
128 var startX = phoneStage.width - 2;
128 var startX = phoneStage.width - 2;
129 var startY = phoneStage.height / 2;
129 var startY = phoneStage.height / 2;
130 var endY = startY;
130 var endY = startY;
131− var endX = units.gu(2);
131+ var endX = phoneStage.width / 2;
132
132
133 touchFlick(phoneStage, startX, startY, endX, endY,
133 touchFlick(phoneStage, startX, startY, endX, endY,
134 true /* beginTouch */, true /* endTouch */, units.gu(10), 50);
134 true /* beginTouch */, true /* endTouch */, units.gu(10), 50);
135+
136+ tryCompare(spreadView, "phase", 2);
137+ waitForRendering(phoneStage);
135 }
138 }
136
139
137 function test_shortFlick() {
140 function test_shortFlick() {
138 addApps(2)
141 addApps(2)
139 var startX = phoneStage.width - units.gu(1);
142 var startX = phoneStage.width - units.gu(1);
140 var startY = phoneStage.height / 2;
143 var startY = phoneStage.height / 2;
141− var endX = phoneStage.width / 2;
144+ var endX = startX - units.gu(4);
142 var endY = startY;
145 var endY = startY;
143
146
144 var activeApp = ApplicationManager.get(0);
147 var activeApp = ApplicationManager.get(0);
@@ -164,7 +167,7 @@ Item {
164 {tag: "<position2 (non-linear)", positionMarker: "positionMarker2", linear: false, offset: -1, endPhase: 0, targetPhase: 0, newFocusedIndex: 1 },
167 {tag: "<position2 (non-linear)", positionMarker: "positionMarker2", linear: false, offset: -1, endPhase: 0, targetPhase: 0, newFocusedIndex: 1 },
165 {tag: ">position2", positionMarker: "positionMarker2", linear: true, offset: +1, endPhase: 1, targetPhase: 0, newFocusedIndex: 1 },
168 {tag: ">position2", positionMarker: "positionMarker2", linear: true, offset: +1, endPhase: 1, targetPhase: 0, newFocusedIndex: 1 },
166 {tag: "<position3", positionMarker: "positionMarker3", linear: true, offset: -1, endPhase: 1, targetPhase: 0, newFocusedIndex: 1 },
169 {tag: "<position3", positionMarker: "positionMarker3", linear: true, offset: -1, endPhase: 1, targetPhase: 0, newFocusedIndex: 1 },
167− {tag: ">position3", positionMarker: "positionMarker3", linear: true, offset: +1, endPhase: 2, targetPhase: 2, newFocusedIndex: 2 },
170+ {tag: ">position3", positionMarker: "positionMarker3", linear: true, offset: +1, endPhase: 1, targetPhase: 2, newFocusedIndex: 2 },
168 ];
171 ];
169 }
172 }
170
173
@@ -386,6 +389,8 @@ Item {
386 compare(dragArea0.enabled, false);
389 compare(dragArea0.enabled, false);
387 compare(dragArea1.enabled, false);
390 compare(dragArea1.enabled, false);
388 compare(dragArea2.enabled, false);
391 compare(dragArea2.enabled, false);
392+
393+ tryCompare(spreadView, "contentX", -spreadView.shift)
389 }
394 }
390 }
395 }
391}
396}