Unity 8
TutorialBottom.qml
1 /*
2  * Copyright (C) 2015 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 import QtQuick 2.4
18 import Ubuntu.Components 1.3
19 import Ubuntu.Gestures 0.1
20 import Unity.Application 0.1
21 
22 TutorialPage {
23  id: root
24 
25  property string usageScenario
26  property var stage
27  property var application: null
28 
29  // This page is a bit fragile. It relies on knowing how the app beneath
30  // the shell will react to a drag. What we do is put a monitor-only DDA
31  // at the bottom of the page (so that we know when the drag is finished)
32  // and pass the events on through to the app. Thus, it sees the drag and
33  // brings its bottom edge up.
34  //
35  // Unfortunately, each app is on its own when implementing the bottom edge
36  // drag. Most share copied-and-pasted code right now, but they will
37  // eventually consolidate on a version of DirectionalDragArea that will
38  // land in the SDK (making our guessing job easier). Though, also in the
39  // future, this whole bottom tutorial component will also land in the SDK,
40  // rendering our version here obsolete.
41  //
42  // Anyway, for the moment, we base our guesses on the copied-and-pasted
43  // code used in several of the core apps and only bring this component
44  // up if we are in those core apps.
45 
46  readonly property real mainStageWidth: stage.width - sideStageWidth
47  readonly property real sideStageWidth: root.usageScenario === "tablet" && stage.sideStageVisible ?
48  stage.sideStageWidth : 0
49  readonly property bool isMainStageApp: usageScenario !== "tablet" ||
50  stage.stageFocusedSurface === ApplicationInfoInterface.MainStage
51  readonly property real dragAreaHeight: units.gu(3) // based on PageWithBottomEdge.qml
52  readonly property real targetDistance: height * 0.2 + dragAreaHeight // based on PageWithBottomEdge.qml
53 
54  opacityOverride: dragArea.dragging ? 1 - (dragArea.distance / targetDistance) : 1
55 
56  mouseArea {
57  anchors.bottomMargin: root.dragAreaHeight
58  }
59 
60  background {
61  sourceSize.height: 1916
62  sourceSize.width: 1080
63  source: Qt.resolvedUrl("graphics/background2.png")
64  rotation: 180
65  }
66 
67  arrow {
68  anchors.bottom: root.bottom
69  anchors.bottomMargin: units.gu(3)
70  anchors.horizontalCenter: label.horizontalCenter
71  anchors.horizontalCenterOffset: -(label.width - label.contentWidth) / 2
72  rotation: 90
73  }
74 
75  label {
76  text: !application ? "" :
77  application.appId === "address-book-app" ?
78  i18n.tr("Swipe up to add a contact") :
79  application.appId === "com.ubuntu.calculator_calculator" ?
80  i18n.tr("Swipe up for favorite calculations") :
81  application.appId === "dialer-app" ?
82  i18n.tr("Swipe up for recent calls") :
83  application.appId === "messaging-app" ?
84  i18n.tr("Swipe up to create a message") :
85  i18n.tr("Swipe up to manage the app") // shouldn't be used
86  anchors.bottom: arrow.top
87  anchors.bottomMargin: units.gu(3)
88  anchors.left: root.left
89  anchors.leftMargin: (label.width - label.contentWidth) / 2 + sideMargin +
90  (isMainStageApp ? 0 : mainStageWidth)
91  width: (isMainStageApp ? mainStageWidth : sideStageWidth) - sideMargin * 2
92 
93  readonly property real sideMargin: units.gu(4)
94  }
95 
96  // Watches drag events but does not intercept them, so that the app beneath
97  // will still drag the bottom edge up.
98  SwipeArea {
99  id: dragArea
100  grabGesture: false
101  direction: Direction.Upwards
102  anchors.left: parent.left
103  anchors.right: parent.right
104  anchors.bottom: parent.bottom
105  height: root.dragAreaHeight
106 
107  // Apps currently don't use DDA. DDA will stop a gesture if
108  // horizontal motion is detected. But our apps won't. So turn off
109  // that gesture cleverness on our part, it will only get us out of sync.
110  immediateRecognition: true
111  }
112 
113  MouseArea {
114  // A second mouse area because in tablet mode, we only want to let the
115  // user drag up on one of the stages, not both. So we want to cover
116  // the second bottom edge with an event eater.
117  enabled: root.usageScenario === "tablet"
118  height: root.dragAreaHeight
119  width: isMainStageApp ? sideStageWidth : mainStageWidth
120  anchors.bottom: parent.bottom
121  anchors.left: isMainStageApp ? undefined : parent.left
122  anchors.right: isMainStageApp ? parent.right : undefined
123  }
124 }