on xenial help sign in
Make tablet mode work better for tutorial
commit35b5baa6eaffb9bd2ada790a32d104688c9a766b authorMichael Terry <michael.terry@canonical.com> dateTue 17 Nov 2015, 11:07 (11 years ago) parent02f0ecb
5 files changed+59−24
qml/Stages/AbstractStage.qml+1 qml/Stages/PhoneStage.qml+1−1 qml/Stages/TabletStage.qml+13−11 qml/Tutorial/TutorialBottom.qml+31−6 qml/Tutorial/TutorialContent.qml+13−6
qml/Stages/AbstractStage.qml+1
@@ -28,6 +28,7 @@ Rectangle {
2828 property url background
2929 property bool beingResized
3030 property int dragAreaWidth
31+ property real dragProgress
3132 property bool interactive
3233 property real inverseProgress // This is the progress for left edge drags, in pixels.
3334 property bool keepDashRunning: true
qml/Stages/PhoneStage.qml+1−1
@@ -84,7 +84,7 @@ AbstractStage {
8484 && spreadView.phase === 0
8585
8686 // How far left the stage has been dragged
87− readonly property real dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).progress : 0
87+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0
8888
8989 readonly property alias dragging: spreadDragArea.dragging
9090
qml/Stages/TabletStage.qml+13−11
@@ -27,6 +27,9 @@ AbstractStage {
2727 objectName: "stages"
2828 anchors.fill: parent
2929
30+ property bool sideStageVisible: priv.sideStageAppId
31+ property real sideStageWidth: units.gu(40)
32+
3033 // Functions to be called from outside
3134 function updateFocusedAppOrientation() {
3235 var mainStageAppIndex = priv.indexOf(priv.mainStageAppId);
@@ -71,6 +74,7 @@ AbstractStage {
7174 }
7275
7376 orientationChangesEnabled: priv.mainAppOrientationChangesEnabled
77+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0
7478
7579 onWidthChanged: {
7680 spreadView.selectedIndex = -1;
@@ -233,8 +237,6 @@ AbstractStage {
233237 contentX: -shift
234238
235239 property int tileDistance: units.gu(20)
236− property int sideStageWidth: units.gu(40)
237− property bool sideStageVisible: priv.sideStageAppId
238240
239241 // This indicates when the spreadView is active. That means, all the animations
240242 // are activated and tiles need to line up for the spread.
@@ -254,14 +256,14 @@ AbstractStage {
254256 // 2: The list is dragged further and snaps into the spread view when entering phase 2
255257 property int phase
256258
257− readonly property int phase0Width: sideStageWidth
258− readonly property int phase1Width: sideStageWidth
259+ readonly property int phase0Width: root.sideStageWidth
260+ readonly property int phase1Width: root.sideStageWidth
259261
260262 // Those markers mark the various positions in the spread (ratio to screen width from right to left):
261263 // 0 - 1: following finger, snap back to the beginning on release
262264 readonly property real positionMarker1: 0.2
263265 // 1 - 2: curved snapping movement, snap to nextInStack on release
264− readonly property real positionMarker2: sideStageWidth / spreadView.width
266+ readonly property real positionMarker2: root.sideStageWidth / spreadView.width
265267 // 2 - 3: movement follows finger, snaps to phase 2 (full spread) on release
266268 readonly property real positionMarker3: 0.6
267269 // passing 3, we detach movement from the finger and snap to phase 2 (full spread)
@@ -490,7 +492,7 @@ AbstractStage {
490492 Rectangle {
491493 id: sideStageBackground
492494 color: "black"
493− width: spreadView.sideStageWidth * (1 - sideStageDragHandle.progress)
495+ width: root.sideStageWidth * (1 - sideStageDragHandle.progress)
494496 height: priv.landscapeHeight
495497 x: spreadView.width - width
496498 z: spreadView.indexToZIndex(priv.indexOf(priv.sideStageAppId))
@@ -505,16 +507,16 @@ AbstractStage {
505507 width: units.gu(2)
506508 height: priv.landscapeHeight
507509 z: sideStageBackground.z
508− opacity: spreadView.phase <= 0 && spreadView.sideStageVisible ? 1 : 0
510+ opacity: spreadView.phase <= 0 && root.sideStageVisible ? 1 : 0
509511 property real progress: 0
510512 property bool dragging: false
511513
512514 Behavior on opacity { UbuntuNumberAnimation {} }
513515
514516 Connections {
515− target: spreadView
517+ target: root
516518 onSideStageVisibleChanged: {
517− if (spreadView.sideStageVisible) {
519+ if (root.sideStageVisible) {
518520 sideStageDragHandle.progress = 0;
519521 }
520522 }
@@ -546,7 +548,7 @@ AbstractStage {
546548 onMouseXChanged: {
547549 totalDiff += mouseX - startX;
548550 if (priv.mainStageAppId) {
549− sideStageDragHandle.progress = Math.max(0, totalDiff / spreadView.sideStageWidth);
551+ sideStageDragHandle.progress = Math.max(0, totalDiff / root.sideStageWidth);
550552 }
551553 gesturePoints.push(mouseX);
552554 }
@@ -586,7 +588,7 @@ AbstractStage {
586588 if (wantsMainStage) {
587589 return spreadView.width;
588590 } else {
589− return spreadView.sideStageWidth;
591+ return root.sideStageWidth;
590592 }
591593 }
592594 height: {
qml/Tutorial/TutorialBottom.qml+31−6
@@ -17,10 +17,15 @@
1717import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Ubuntu.Gestures 0.1
20+import Unity.Application 0.1
2021
2122TutorialPage {
2223 id: root
2324
25+ property string usageScenario
26+ property var stage
27+ property var application: null
28+
2429 // This page is a bit fragile. It relies on knowing how the app beneath
2530 // the shell will react to a drag. What we do is put a monitor-only DDA
2631 // at the bottom of the page (so that we know when the drag is finished)
@@ -46,6 +51,10 @@ TutorialPage {
4651 appId === "messaging-app";
4752 }
4853
54+ readonly property real mainStageWidth: stage.width - sideStageWidth
55+ readonly property real sideStageWidth: root.usageScenario === "tablet" && stage.sideStageVisible ?
56+ stage.sideStageWidth : 0
57+ readonly property bool isMainStageApp: application.stage === ApplicationInfoInterface.MainStage
4958 readonly property real dragAreaHeight: units.gu(3) // based on PageWithBottomEdge.qml
5059 readonly property real targetDistance: height * 0.2 + dragAreaHeight // based on PageWithBottomEdge.qml
5160
@@ -65,7 +74,8 @@ TutorialPage {
6574 arrow {
6675 anchors.bottom: root.bottom
6776 anchors.bottomMargin: units.gu(4)
68− anchors.horizontalCenter: root.horizontalCenter
77+ anchors.horizontalCenter: label.horizontalCenter
78+ anchors.horizontalCenterOffset: -(label.width - label.contentWidth) / 2
6979 rotation: -90
7080 }
7181
@@ -73,9 +83,12 @@ TutorialPage {
7383 text: i18n.tr("Swipe from the bottom edge to manage the app")
7484 anchors.bottom: arrow.top
7585 anchors.bottomMargin: units.gu(3)
76− anchors.horizontalCenter: root.horizontalCenter
77− anchors.horizontalCenterOffset: (label.width - label.contentWidth) / 2
78− width: root.width - units.gu(8)
86+ anchors.left: root.left
87+ anchors.leftMargin: (label.width - label.contentWidth) / 2 + sideMargin +
88+ (isMainStageApp ? 0 : mainStageWidth)
89+ width: (isMainStageApp ? mainStageWidth : sideStageWidth) - sideMargin * 2
90+
91+ readonly property real sideMargin: units.gu(4)
7992 }
8093
8194 // Watches drag events but does not intercept them, so that the app beneath
@@ -89,9 +102,21 @@ TutorialPage {
89102 anchors.bottom: parent.bottom
90103 height: root.dragAreaHeight
91104
92− // Because apps currently don't use DDA, and DDA will stop a gesture if
93− // horizontal motion is detected. But our apps wont'. So turn off
105+ // Apps currently don't use DDA. DDA will stop a gesture if
106+ // horizontal motion is detected. But our apps won't. So turn off
94107 // that gesture cleverness on our part, it will only get us out of sync.
95108 immediateRecognition: true
96109 }
110+
111+ MouseArea {
112+ // A second mouse area because in tablet mode, we only want to let the
113+ // user drag up on one of the stages, not both. So we want to cover
114+ // the second bottom edge with an event eater.
115+ enabled: root.usageScenario === "tablet"
116+ height: root.dragAreaHeight
117+ width: isMainStageApp ? sideStageWidth : mainStageWidth
118+ anchors.bottom: parent.bottom
119+ anchors.left: isMainStageApp ? undefined : parent.left
120+ anchors.right: isMainStageApp ? parent.right : undefined
121+ }
97122}
qml/Tutorial/TutorialContent.qml+13−6
@@ -55,6 +55,10 @@ Item {
5555 root.usageScenario === "phone" ||
5656 root.usageScenario === "tablet"
5757
58+ property var focusedApp: ApplicationManager.focusedApplicationId
59+ ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
60+ : null
61+
5862 property bool endPointsFinished: tutorialRight.skipped && tutorialBottom.skipped
5963 onEndPointsFinishedChanged: if (endPointsFinished) root.finish()
6064 }
@@ -130,10 +134,10 @@ Item {
130134 }
131135
132136 Connections {
133− target: stage
134− onMainAppChanged: {
135− if (tutorialRight.isReady && !tutorialRight.shown && stage.mainApp
136− && stage.mainApp.state === ApplicationInfoInterface.Starting) {
137+ target: d
138+ onFocusedAppChanged: {
139+ if (tutorialRight.isReady && !tutorialRight.shown && d.focusedApp
140+ && d.focusedApp.state === ApplicationInfoInterface.Starting) {
137141 tutorialRight.show();
138142 }
139143 }
@@ -150,13 +154,16 @@ Item {
150154 anchors.fill: parent
151155 hides: [launcher, panel.indicators]
152156 paused: root.paused
157+ usageScenario: root.usageScenario
158+ stage: root.stage
159+ application: d.focusedApp
153160
154161 readonly property bool skipped: !d.mobileScenario ||
155162 AccountsService.demoEdgesCompleted.indexOf("bottom") != -1
156− readonly property bool mightShow: !skipped && stage.mainApp && canShowForApp(stage.mainApp.appId)
163+ readonly property bool mightShow: !skipped && d.focusedApp && canShowForApp(d.focusedApp.appId)
157164 isReady: !skipped && !paused && !keyboardVisible &&
158165 !tutorialTop.shown && !tutorialRight.shown &&
159− mightShow && stage.mainApp.state === ApplicationInfoInterface.Running
166+ mightShow && d.focusedApp.state === ApplicationInfoInterface.Running
160167
161168 onSkippedChanged: if (skipped && shown) hide()
162169 onIsReadyChanged: if (isReady && !shown) show()