Unity 8
NarrowView.qml
1 /*
2  * Copyright (C) 2015-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 QtQuick.Window 2.2
19 import Ubuntu.Components 1.3
20 import Ubuntu.Telephony 0.1 as Telephony
21 import "../Components"
22 
23 FocusScope {
24  id: root
25 
26  property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
27  property alias launcherOffset: coverPage.launcherOffset
28  property alias currentIndex: loginList.currentIndex
29  property alias delayMinutes: delayedLockscreen.delayMinutes
30  property alias backgroundTopMargin: coverPage.backgroundTopMargin
31  property url background
32  property bool hasCustomBackground
33  property bool locked
34  property alias alphanumeric: loginList.alphanumeric
35  property alias userModel: loginList.model
36  property alias infographicModel: coverPage.infographicModel
37  property string sessionToStart
38  property bool waiting
39  readonly property bool fullyShown: coverPage.showProgress === 1 || lockscreen.shown
40  readonly property bool required: coverPage.required || lockscreen.required
41  readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
42 
43  // so that it can be replaced in tests with a mock object
44  property var inputMethod: Qt.inputMethod
45 
46  signal selected(int index)
47  signal responded(string response)
48  signal tease()
49  signal emergencyCall()
50 
51  function hide() {
52  lockscreen.hide();
53  coverPage.hide();
54  }
55 
56  function showFakePassword() {
57  loginList.showFakePassword();
58  }
59 
60  function notifyAuthenticationFailed() {
61  loginList.showError();
62  }
63 
64  function showErrorMessage(msg) {
65  coverPage.showErrorMessage(msg);
66  }
67 
68  function forceShow() {
69  coverPage.show();
70  }
71 
72  function tryToUnlock(toTheRight) {
73  var coverChanged = coverPage.shown;
74  lockscreen.maybeShow();
75  if (toTheRight) {
76  coverPage.hideRight();
77  } else {
78  coverPage.hide();
79  }
80  return coverChanged;
81  }
82 
83  onLockedChanged: {
84  if (locked) {
85  lockscreen.maybeShow();
86  } else {
87  lockscreen.hide();
88  }
89  }
90 
91  Showable {
92  id: lockscreen
93  objectName: "lockscreen"
94  anchors.fill: parent
95  shown: false
96  opacity: 0
97 
98  showAnimation: StandardAnimation { property: "opacity"; to: 1 }
99  hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
100 
101  Rectangle {
102  // In case background fails to load or doesn't cover the whole screen
103  id: backgroundBackup
104  anchors.fill: parent
105  color: "black"
106  }
107 
108  Wallpaper {
109  id: lockscreenBackground
110  objectName: "lockscreenBackground"
111  anchors {
112  fill: parent
113  topMargin: root.backgroundTopMargin
114  }
115  source: root.background
116  }
117 
118  // Darken background to match CoverPage
119  Rectangle {
120  objectName: "lockscreenShade"
121  anchors.fill: parent
122  color: "black"
123  opacity: root.hasCustomBackground ? 0.4 : 0
124  }
125 
126  LoginList {
127  id: loginList
128  objectName: "loginList"
129 
130  anchors {
131  horizontalCenter: parent.horizontalCenter
132  top: parent.top
133  bottom: parent.bottom
134  }
135  width: units.gu(40)
136  boxVerticalOffset: units.gu(14)
137  enabled: !coverPage.shown && visible
138  visible: !delayedLockscreen.visible
139 
140  locked: root.locked
141 
142  onSelected: if (enabled) root.selected(index)
143  onResponded: root.responded(response)
144  }
145 
146  DelayedLockscreen {
147  id: delayedLockscreen
148  objectName: "delayedLockscreen"
149  anchors.fill: parent
150  visible: delayMinutes > 0
151  alphaNumeric: loginList.alphanumeric
152  }
153 
154  function maybeShow() {
155  if (root.locked && !shown) {
156  showNow();
157  }
158  }
159  }
160 
161  Rectangle {
162  anchors.fill: parent
163  color: "black"
164  opacity: coverPage.showProgress * 0.8
165  }
166 
167  CoverPage {
168  id: coverPage
169  objectName: "coverPage"
170  height: parent.height
171  width: parent.width
172  background: root.background
173  hasCustomBackground: root.hasCustomBackground
174  draggable: !root.waiting
175  onTease: root.tease()
176  onClicked: hide()
177 
178  onShowProgressChanged: {
179  if (showProgress === 0) {
180  if (lockscreen.shown) {
181  loginList.tryToUnlock();
182  } else {
183  root.responded("");
184  }
185  }
186  }
187 
188  Clock {
189  anchors {
190  top: parent.top
191  topMargin: units.gu(2)
192  horizontalCenter: parent.horizontalCenter
193  }
194  }
195  }
196 
197  StyledItem {
198  id: bottomBar
199  visible: lockscreen.shown
200  height: units.gu(4)
201 
202  anchors.left: parent.left
203  anchors.right: parent.right
204  anchors.top: parent.bottom
205  anchors.topMargin: - height * (1 - coverPage.showProgress)
206  - (inputMethod && inputMethod.visible ?
207  inputMethod.keyboardRectangle.height : 0)
208 
209  Rectangle {
210  color: UbuntuColors.porcelain // matches OSK background
211  anchors.fill: parent
212  }
213 
214  Label {
215  text: i18n.tr("Cancel")
216  anchors.left: parent.left
217  anchors.leftMargin: units.gu(2)
218  anchors.top: parent.top
219  anchors.bottom: parent.bottom
220  verticalAlignment: Text.AlignVCenter
221  font.weight: Font.Light
222  fontSize: "small"
223  color: UbuntuColors.slate
224 
225  AbstractButton {
226  anchors.fill: parent
227  anchors.leftMargin: -units.gu(2)
228  anchors.rightMargin: -units.gu(2)
229  onClicked: coverPage.show()
230  }
231  }
232 
233  Label {
234  objectName: "emergencyCallLabel"
235  text: callManager.hasCalls ? i18n.tr("Return to Call") : i18n.tr("Emergency")
236  anchors.right: parent.right
237  anchors.rightMargin: units.gu(2)
238  anchors.top: parent.top
239  anchors.bottom: parent.bottom
240  verticalAlignment: Text.AlignVCenter
241  font.weight: Font.Light
242  fontSize: "small"
243  color: UbuntuColors.slate
244  // TODO: uncomment once bug 1616538 is fixed
245  // visible: telepathyHelper.ready && telepathyHelper.emergencyCallsAvailable
246  enabled: visible
247 
248  AbstractButton {
249  anchors.fill: parent
250  anchors.leftMargin: -units.gu(2)
251  anchors.rightMargin: -units.gu(2)
252  onClicked: root.emergencyCall()
253  }
254  }
255  }
256 
257  // FIXME: It's difficult to keep something tied closely to the OSK (bug
258  // 1616163). But as a hack to avoid the background peeking out,
259  // we add an extra Rectangle that just serves to hide the background
260  // during OSK animations.
261  Rectangle {
262  visible: bottomBar.visible
263  height: inputMethod && inputMethod.visible ?
264  inputMethod.keyboardRectangle.height : 0
265  anchors.bottom: parent.bottom
266  anchors.left: parent.left
267  anchors.right: parent.right
268  color: UbuntuColors.porcelain
269  }
270 }