Unity 8
TutorialContent.qml
1 /*
2  * Copyright (C) 2013-2016 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 AccountsService 0.1
20 import Unity.Application 0.1
21 
22 Item {
23  id: root
24 
25  property Item launcher
26  property Item panel
27  property Item stage
28  property string usageScenario
29  property bool paused: true // default to true so that we won't start until top level is all ready
30  property bool delayed: true // same
31  property var lastInputTimestamp
32 
33  readonly property bool launcherEnabled: !running
34  || tutorialLeftLoader.shown
35  || tutorialLeftLongLoader.shown
36  readonly property bool launcherLongSwipeEnabled: tutorialLeftLongLoader.shown
37  || tutorialLeftLongLoader.skipped
38  readonly property bool spreadEnabled: !running || tutorialRightLoader.shown
39  readonly property bool panelEnabled: !running || tutorialTopLoader.shown
40  readonly property bool running: tutorialLeftLoader.shown
41  || tutorialLeftLongLoader.shown
42  || tutorialTopLoader.shown
43  || tutorialRightLoader.shown
44 
45  signal finished()
46 
47  function finish() {
48  finished();
49  }
50 
51  ////
52 
53  QtObject {
54  id: d
55 
56  // We allow "" because it is briefly empty on startup, and we don't
57  // want to improperly skip any mobile tutorials.
58  property bool mobileScenario: root.usageScenario === "" ||
59  root.usageScenario === "phone" ||
60  root.usageScenario === "tablet"
61 
62  function haveShown(tutorialId) {
63  return AccountsService.demoEdgesCompleted.indexOf(tutorialId) != -1;
64  }
65 
66  property bool endPointsFinished: tutorialRightLoader.skipped
67  onEndPointsFinishedChanged: if (endPointsFinished) root.finish()
68  }
69 
70  Loader {
71  id: tutorialLeftLoader
72  objectName: "tutorialLeftLoader"
73  anchors.fill: parent
74 
75  readonly property bool skipped: !d.mobileScenario || d.haveShown("left")
76  readonly property bool shown: item && item.shown
77  active: !skipped || (item && item.visible)
78  onSkippedChanged: if (skipped && shown) item.hide()
79 
80  sourceComponent: TutorialLeft {
81  id: tutorialLeft
82  objectName: "tutorialLeft"
83  anchors.fill: parent
84  launcher: root.launcher
85  hides: [launcher, panel.indicators]
86  paused: root.paused
87 
88  isReady: !tutorialLeftLoader.skipped && !paused && !delayed
89 
90  InactivityTimer {
91  id: tutorialLeftTimer
92  objectName: "tutorialLeftTimer"
93  interval: 20000
94  lastInputTimestamp: root.lastInputTimestamp
95  page: parent
96  }
97 
98  onIsReadyChanged: if (isReady && !shown) tutorialLeftTimer.start()
99  onFinished: AccountsService.markDemoEdgeCompleted("left")
100  }
101  }
102 
103  Loader {
104  id: tutorialTopLoader
105  objectName: "tutorialTopLoader"
106  anchors.fill: parent
107 
108  readonly property bool skipped: !d.mobileScenario || d.haveShown("top")
109  readonly property bool shown: item && item.shown
110  active: !skipped || (item && item.visible)
111  onSkippedChanged: if (skipped && shown) item.hide()
112 
113  sourceComponent: TutorialTop {
114  id: tutorialTop
115  objectName: "tutorialTop"
116  anchors.fill: parent
117  panel: root.panel
118  hides: [launcher, panel.indicators]
119  paused: root.paused
120 
121  skipped: tutorialTopLoader.skipped
122  isReady: tutorialLeftLoader.skipped && !skipped && !paused && !delayed
123 
124  InactivityTimer {
125  id: tutorialTopTimer
126  objectName: "tutorialTopTimer"
127  interval: 60000
128  lastInputTimestamp: root.lastInputTimestamp
129  page: parent
130  }
131 
132  onIsReadyChanged: if (isReady && !shown) tutorialTopTimer.start()
133  onFinished: AccountsService.markDemoEdgeCompleted("top")
134  }
135  }
136 
137  Loader {
138  id: tutorialLeftLongLoader
139  objectName: "tutorialLeftLongLoader"
140  anchors.fill: parent
141 
142  readonly property bool skipped: !d.mobileScenario || d.haveShown("left-long")
143  readonly property bool shown: item && item.shown
144  active: !skipped || (item && item.visible)
145  onSkippedChanged: if (skipped && shown) item.hide()
146 
147  sourceComponent: TutorialLeftLong {
148  id: tutorialLeftLong
149  objectName: "tutorialLeftLong"
150  anchors.fill: parent
151  launcher: root.launcher
152  hides: [launcher, panel.indicators]
153  paused: root.paused
154 
155  skipped: tutorialLeftLongLoader.skipped
156  isReady: tutorialTopLoader.skipped && !skipped && !paused && !delayed
157 
158  InactivityTimer {
159  id: tutorialLeftLongTimer
160  objectName: "tutorialLeftLongTimer"
161  interval: 5000
162  lastInputTimestamp: root.lastInputTimestamp
163  page: parent
164  }
165 
166  onIsReadyChanged: if (isReady && !shown) tutorialLeftLongTimer.start()
167  onFinished: AccountsService.markDemoEdgeCompleted("left-long")
168  }
169  }
170 
171  Loader {
172  id: tutorialRightLoader
173  objectName: "tutorialRightLoader"
174  anchors.fill: parent
175 
176  readonly property bool skipped: d.haveShown("right")
177  readonly property bool shown: item && item.shown
178  active: !skipped || (item && item.visible)
179  onSkippedChanged: if (skipped && shown) item.hide()
180 
181  sourceComponent: TutorialRight {
182  id: tutorialRight
183  objectName: "tutorialRight"
184  anchors.fill: parent
185  stage: root.stage
186  usageScenario: root.usageScenario
187  hides: [launcher, panel.indicators]
188  paused: root.paused
189 
190  skipped: tutorialRightLoader.skipped
191  isReady: tutorialTopLoader.skipped && !skipped && !paused && !delayed &&
192  ApplicationManager.count >= 4
193 
194  InactivityTimer {
195  id: tutorialRightTimer
196  objectName: "tutorialRightTimer"
197  interval: 10000
198  lastInputTimestamp: root.lastInputTimestamp
199  page: parent
200  }
201 
202  onIsReadyChanged: if (isReady && !shown) tutorialRightTimer.start()
203  onFinished: AccountsService.markDemoEdgeCompleted("right")
204  }
205  }
206 }