@@ -19,6 +19,7 @@ import Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
20import Ubuntu.Gestures 0.1
21import LightDM 0.1 as LightDM
21import LightDM 0.1 as LightDM
22+import AccountsService 0.1
22import Powerd 0.1
23import Powerd 0.1
23import "Dash"
24import "Dash"
24import "Greeter"
25import "Greeter"
@@ -58,6 +59,19 @@ FocusScope {
62+ property bool showEdgeDemo: false
63+ property bool showEdgeDemoInGreeter: showEdgeDemo //AccountsService.getUserProperty("lightdm", "demo-edges")
65+ function hideEdgeDemo() {
66+ var user = LightDM.Users.data(greeter.currentIndex, LightDM.UserRoles.NameRole);
67+ AccountsService.setUserProperty(user, "demo-edges", false);
68+ shell.showEdgeDemo = false;
70+ function hideEdgeDemoInGreeter() {
71+ //AccountsService.setUserProperty("lightdm", "demo-edges", false);
72+ shell.showEdgeDemoInGreeter = false;
61 property ListModel searchHistory: SearchHistoryModel {}
75 property ListModel searchHistory: SearchHistoryModel {}
63 property var applicationManager: ApplicationManagerWrapper {}
77 property var applicationManager: ApplicationManagerWrapper {}
@@ -160,7 +174,7 @@ FocusScope {
160 available: !greeter.shown && !lockscreen.shown
174 available: !greeter.shown && !lockscreen.shown
161 hides: [stages, launcher, panel.indicators]
175 hides: [stages, launcher, panel.indicators]
162 shown: disappearingAnimationProgress !== 1.0
176 shown: disappearingAnimationProgress !== 1.0
163− enabled: disappearingAnimationProgress === 0.0
177+ enabled: disappearingAnimationProgress === 0.0 && !leftEdgeDemo.active && !topEdgeDemo.active && !finalEdgeDemo.active
164 // FIXME: unfocus all applications when going back to the dash
178 // FIXME: unfocus all applications when going back to the dash
165 onEnabledChanged: {
179 onEnabledChanged: {
166 if (enabled) {
180 if (enabled) {
@@ -187,6 +201,50 @@ FocusScope {
187 // greeterRevealer.animatedProgress are not animated
201 // greeterRevealer.animatedProgress are not animated
188 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
202 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
209+ title: i18n.tr("Top edge")
210+ text: i18n.tr("Try swiping from the top edge to access the indicators")
213+ enabled: shell.showEdgeDemo
214+ onSkip: shell.hideEdgeDemo()
218+ onShownChanged: if (!greeter.shown) topEdgeDemo.visible = true
222+ target: panel.indicators
223+ onFullyOpenedChanged: if (panel.indicators.fullyOpened) topEdgeDemo.enabled = false
231+ title: i18n.tr("Left edge")
232+ text: i18n.tr("Swipe from the left to reveal the launcher for quick access to apps")
235+ enabled: shell.showEdgeDemo
236+ onSkip: shell.hideEdgeDemo()
239+ target: bottomEdgeDemo
240+ onActiveChanged: if (!bottomEdgeDemo.active) leftEdgeDemo.visible = true
245+ onProgressChanged: if (launcher.progress >= 1.0) leftEdgeDemo.enabled = false
@@ -381,6 +439,7 @@ FocusScope {
381 Component.onCompleted: {
439 Component.onCompleted: {
382 if (LightDM.Users.count == 1) {
440 if (LightDM.Users.count == 1) {
383 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
441 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
@@ -423,6 +482,7 @@ FocusScope {
423 // If there are more users, the Greeter will handle that
482 // If there are more users, the Greeter will handle that
424 if (LightDM.Users.count == 1) {
483 if (LightDM.Users.count == 1) {
425 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
484 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
485+ greeter.selected(0);
427 greeter.forceActiveFocus();
487 greeter.forceActiveFocus();
@@ -430,8 +490,12 @@ FocusScope {
431 onUnlocked: greeter.hide()
491 onUnlocked: greeter.hide()
432 onSelected: {
492 onSelected: {
493+ // Update background
433 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
494 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
434 shell.background = bgPath ? bgPath : default_background
495 shell.background = bgPath ? bgPath : default_background
496+ // Update edge demo hint
497+ var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole)
498+ shell.showEdgeDemo = AccountsService.getUserProperty(user, "demo-edges")
437 onLeftTeaserPressedChanged: {
501 onLeftTeaserPressedChanged: {
@@ -439,6 +503,34 @@ FocusScope {
439 launcher.tease();
503 launcher.tease();
511+ title: i18n.tr("Right edge")
512+ text: i18n.tr("Try swiping from the right edge to unlock the phone")
513+ anchors.fill: parent
514+ visible: shell.showEdgeDemoInGreeter
516+ shell.hideEdgeDemoInGreeter()
517+ shell.hideEdgeDemo()
524+ if (rightEdgeDemo.active) {
525+ rightEdgeDemo.enabled = false
526+ shell.hideEdgeDemoInGreeter()
531+ onShownChanged: if (!greeter.shown) hide()
444 InputFilterArea {
536 InputFilterArea {
@@ -493,6 +585,7 @@ FocusScope {
493 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
585 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
494 indicators {
586 indicators {
495 hides: [launcher]
587 hides: [launcher]
588+ available: !rightEdgeDemo.active && !leftEdgeDemo.active && !finalEdgeDemo.active
497 fullscreenMode: shell.fullscreenMode
590 fullscreenMode: shell.fullscreenMode
498 searchVisible: !greeter.shown && !lockscreen.shown
591 searchVisible: !greeter.shown && !lockscreen.shown
@@ -501,6 +594,24 @@ FocusScope {
501 anchors.fill: parent
594 anchors.fill: parent
502 blockInput: panel.indicators.shown
595 blockInput: panel.indicators.shown
602+ title: i18n.tr("Close")
603+ text: i18n.tr("Swipe up again to close the settings screen")
604+ anchors.fill: panel.indicators
606+ enabled: shell.showEdgeDemo
607+ onSkip: shell.hideEdgeDemo()
610+ target: panel.indicators
611+ onFullyOpenedChanged: if (panel.indicators.fullyOpened) bottomEdgeDemo.visible = true
612+ onPartiallyOpenedChanged: if (!panel.indicators.partiallyOpened && !panel.indicators.fullyOpened) bottomEdgeDemo.enabled = false
@@ -509,7 +620,7 @@ FocusScope {
509 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
620 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
510 height: parent.height
621 height: parent.height
512− available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown
623+ available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown && !topEdgeDemo.active
513 shown: false
624 shown: false
514 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
625 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
515 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
626 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
@@ -567,7 +678,7 @@ FocusScope {
567 anchors.bottom: parent.bottom
678 anchors.bottom: parent.bottom
568 width: parent.width
679 width: parent.width
569 dragAreaWidth: shell.edgeSize
680 dragAreaWidth: shell.edgeSize
570− available: !greeter.shown || greeter.narrowMode
681+ available: (!greeter.shown || greeter.narrowMode) && !rightEdgeDemo.active && !topEdgeDemo.active && !bottomEdgeDemo.active && !finalEdgeDemo.active
571 onDashItemSelected: {
682 onDashItemSelected: {
572 greeter.hide()
683 greeter.hide()
573 // Animate if moving between application and dash
684 // Animate if moving between application and dash
@@ -625,6 +736,27 @@ FocusScope {
743+ title: i18n.tr("Well done")
744+ text: i18n.tr("You have now mastered the edge gestures and can start using the phone")
745+ skipText: i18n.tr("Finish")
746+ anchors.fill: overlay
748+ enabled: shell.showEdgeDemo
751+ shell.hideEdgeDemo();
755+ target: leftEdgeDemo
756+ onActiveChanged: if (!leftEdgeDemo.active) finalEdgeDemo.visible = true
628 focus: true
760 focus: true
630 InputFilterArea {
762 InputFilterArea {