2 * Copyright (C) 2013,2014 Canonical, Ltd.
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.
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.
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/>.
18import Ubuntu.Components 1.3
19import AccountsService 0.1
20import Unity.Application 0.1
25 property Item launcher
28 property string usageScenario
30 property bool keyboardVisible
31 property var lastInputTimestamp
33 readonly property bool launcherEnabled: !running
34 || tutorialLeftLoader.shown
35 || tutorialLeftLongLoader.shown
36 readonly property bool spreadEnabled: !running || tutorialRightLoader.shown
37 readonly property bool panelEnabled: !running || tutorialTopLoader.shown
38 readonly property bool running: tutorialLeftLoader.shown
39 || tutorialTopLoader.shown
40 || tutorialRightLoader.shown
41 || tutorialBottomLoader.shown
54 // We allow "" because it is briefly empty on startup, and we don't
55 // want to improperly skip any mobile tutorials.
56 property bool mobileScenario: root.usageScenario === "" ||
57 root.usageScenario === "phone" ||
58 root.usageScenario === "tablet"
60 property var focusedApp: ApplicationManager.focusedApplicationId
61 ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
64 function haveShown(tutorialId) {
65 return AccountsService.demoEdgesCompleted.indexOf(tutorialId) != -1;
68 property bool endPointsFinished: tutorialRightLoader.skipped &&
69 tutorialBottomLoader.skipped
70 onEndPointsFinishedChanged: if (endPointsFinished) root.finish()
74 id: tutorialLeftLoader
75 objectName: "tutorialLeftLoader"
78 readonly property bool skipped: !d.mobileScenario || d.haveShown("left")
79 readonly property bool shown: item && item.shown
80 active: !skipped || (item && item.visible)
81 onSkippedChanged: if (skipped && shown) item.hide()
83 sourceComponent: TutorialLeft {
85 objectName: "tutorialLeft"
87 launcher: root.launcher
88 hides: [launcher, panel.indicators]
91 isReady: !tutorialLeftLoader.skipped && !paused && !keyboardVisible &&
92 !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow
94 // Use an idle timer here, because when constructed, all our isReady variables will be false.
95 // Qml needs a moment to copy their values from Tutorial.qml. So we idle it and recheck.
99 onTriggered: if (tutorialLeft.isReady && !tutorialLeft.shown) tutorialLeft.show()
102 onIsReadyChanged: if (isReady && !shown) tutorialLeftTimer.start()
103 onFinished: AccountsService.markDemoEdgeCompleted("left")
108 id: tutorialLeftLongLoader
109 objectName: "tutorialLeftLongLoader"
112 readonly property bool skipped: !d.mobileScenario || d.haveShown("left-long")
113 readonly property bool shown: item && item.shown
114 active: !skipped || (item && item.visible)
115 onSkippedChanged: if (skipped && shown) item.hide()
117 sourceComponent: TutorialLeftLong {
119 objectName: "tutorialLeftLong"
121 launcher: root.launcher
122 hides: [launcher, panel.indicators]
125 skipped: tutorialLeftLongLoader.skipped
126 isReady: tutorialLeftLoader.skipped && !skipped && !paused && !keyboardVisible &&
127 !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow
130 id: tutorialLeftLongTimer
131 objectName: "tutorialLeftLongTimer"
134 if (parent.isReady) {
138 } else if (!parent.skipped) {
144 onIsReadyChanged: if (isReady && !shown) tutorialLeftLongTimer.start()
145 onFinished: AccountsService.markDemoEdgeCompleted("left-long")
150 id: tutorialTopLoader
151 objectName: "tutorialTopLoader"
154 readonly property bool skipped: !d.mobileScenario || d.haveShown("top")
155 readonly property bool shown: item && item.shown
156 active: !skipped || (item && item.visible)
157 onSkippedChanged: if (skipped && shown) item.hide()
159 sourceComponent: TutorialTop {
161 objectName: "tutorialTop"
164 hides: [launcher, panel.indicators]
167 skipped: tutorialTopLoader.skipped
168 isReady: tutorialLeftLongLoader.skipped && !skipped && !paused && !keyboardVisible &&
169 !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow
171 // We fire 30s after left edge tutorial, with at least 3s of inactivity
174 id: tutorialTopInactivityTimer
175 lastInputTimestamp: root.lastInputTimestamp
181 objectName: "tutorialTopTimer"
183 onTriggered: tutorialTopInactivityTimer.start()
186 onIsReadyChanged: if (isReady && !shown) tutorialTopTimer.start()
187 onFinished: AccountsService.markDemoEdgeCompleted("top")
192 id: tutorialRightLoader
193 objectName: "tutorialRightLoader"
196 readonly property bool skipped: d.haveShown("right")
197 readonly property bool shown: item && item.shown
198 active: !skipped || (item && item.visible)
199 onSkippedChanged: if (skipped && shown) item.hide()
201 sourceComponent: TutorialRight {
203 objectName: "tutorialRight"
206 usageScenario: root.usageScenario
207 hides: [launcher, panel.indicators]
210 skipped: tutorialRightLoader.skipped
211 isReady: tutorialTopLoader.skipped && !skipped && !paused && !keyboardVisible &&
212 !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow &&
213 ApplicationManager.count >= 3
216 id: tutorialRightInactivityTimer
217 objectName: "tutorialRightInactivityTimer"
218 lastInputTimestamp: root.lastInputTimestamp
224 onFocusedAppChanged: {
225 if (tutorialRight.isReady && !tutorialRight.shown && d.focusedApp
226 && d.focusedApp.state === ApplicationInfoInterface.Starting) {
227 tutorialRight.show();
232 onIsReadyChanged: if (isReady && !shown) tutorialRightInactivityTimer.start()
233 onFinished: AccountsService.markDemoEdgeCompleted("right")
238 id: tutorialBottomLoader
239 objectName: "tutorialBottomLoader"
242 // See TutorialBottom.qml for an explanation of why we only support
244 readonly property var supportedApps: ["address-book-app",
245 "com.ubuntu.calculator_calculator",
248 readonly property bool skipped: {
249 if (!d.mobileScenario) {
252 for (var i = 0; i < supportedApps.length; i++) {
253 if (!d.haveShown("bottom-" + supportedApps[i])) {
259 readonly property bool shown: item && item.shown
260 readonly property bool haveShownFocusedApp: d.focusedApp &&
261 d.haveShown("bottom-" + d.focusedApp.appId)
262 readonly property bool mightShow: !skipped && d.focusedApp &&
263 supportedApps.indexOf(d.focusedApp.appId) !== -1 &&
265 active: !skipped || (item && item.visible)
266 onHaveShownFocusedAppChanged: if (haveShownFocusedApp && shown) hide()
267 onSkippedChanged: if (skipped && shown) item.hide()
269 sourceComponent: TutorialBottom {
271 objectName: "tutorialBottom"
273 hides: [launcher, panel.indicators]
275 usageScenario: root.usageScenario
277 application: d.focusedApp
279 skipped: tutorialBottomLoader.skipped
280 isReady: !tutorialBottomLoader.skipped && !paused && !keyboardVisible &&
281 !tutorialLeftLoader.shown && !tutorialLeftLongLoader.shown &&
282 !tutorialTopLoader.shown && !tutorialRightLoader.shown &&
283 tutorialBottomLoader.mightShow &&
284 d.focusedApp.state === ApplicationInfoInterface.Running
286 onIsReadyChanged: if (isReady && !shown) show()
287 onFinished: AccountsService.markDemoEdgeCompleted("bottom-" + d.focusedApp.appId)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list