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