Unity 8
 All Classes Functions
PinLockscreen.qml
1 /*
2  * Copyright (C) 2013 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.0
18 import Ubuntu.Components 0.1
19 import Ubuntu.Components.ListItems 0.1
20 import "../Components"
21 
22 Column {
23  id: root
24  anchors.top: parent.top
25  anchors.topMargin: units.gu(4)
26  anchors.horizontalCenter: parent.horizontalCenter
27  spacing: units.gu(2)
28 
29  property string infoText
30  property string retryText
31  property string errorText
32  property int padWidth: units.gu(34)
33  property int padHeight: units.gu(28)
34  property int minPinLength: -1
35  property int maxPinLength: -1
36  property bool showCancelButton: true
37 
38  readonly property string passphrase: pinentryField.text
39 
40  signal entered(string passphrase)
41  signal cancel()
42 
43  property bool entryEnabled: true
44 
45  function clear(showAnimation) {
46  pinentryField.text = "";
47  if (showAnimation) {
48  pinentryField.incorrectOverride = true;
49  wrongPasswordAnimation.start();
50  }
51  }
52 
53  Column {
54  id: shakeContainer
55  anchors.horizontalCenter: parent.horizontalCenter
56  width: parent.width
57  spacing: units.gu(1)
58 
59  Label {
60  id: infoField
61  objectName: "infoTextLabel"
62  fontSize: "large"
63  color: "#f3f3e7"
64  anchors.horizontalCenter: parent.horizontalCenter
65  text: root.infoText
66  }
67 
68  Item {
69  id: pinContainer
70  anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
71  height: units.gu(4)
72 
73  Row {
74  id: pinentryField
75  objectName: "pinentryField"
76  anchors.horizontalCenter: parent.horizontalCenter
77  anchors.verticalCenter: parent.verticalCenter
78  spacing: Math.max(0, Math.min(units.gu(3), (parent.width / root.maxPinLength) - units.gu(3)))
79 
80  property string text
81  property bool incorrectOverride: false
82 
83  Repeater {
84  model: pinentryField.text.length
85  delegate: Rectangle {
86  color: "#f3f3e7"
87  width: Math.min(units.gu(2), (pinContainer.width - pinContainer.height*2 ) / (root.maxPinLength >= 0 ? root.maxPinLength : 16))
88  height: width
89  radius: width / 2
90  }
91  }
92 
93  function appendNumber(number) {
94  if (incorrectOverride) {
95  incorrectOverride = false;
96  }
97 
98  pinentryField.text = pinentryField.text + number
99 
100  if (root.minPinLength > 0 && root.maxPinLength > 0
101  && root.minPinLength == root.maxPinLength && pinentryField.text.length == root.minPinLength) {
102  root.entered(pinentryField.text)
103  }
104  }
105 
106  function backspace() {
107  pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
108  }
109  }
110  Label {
111  id: wrongNoticeLabel
112  objectName: "wrongNoticeLabel"
113  fontSize: "x-large"
114  color: "#f3f3e7"
115  anchors.horizontalCenter: parent.horizontalCenter
116  horizontalAlignment: Text.AlignHCenter
117  text: root.errorText
118  visible: pinentryField.incorrectOverride
119  scale: Math.min(1, parent.width / width)
120  }
121 
122  AbstractButton {
123  objectName: "backspaceIcon"
124  anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
125  width: height
126 
127  Icon {
128  anchors.fill: parent
129  name: "erase"
130  color: "#f3f3e7"
131  }
132 
133  opacity: (pinentryField.text.length && !pinentryField.incorrectOverride) > 0 ? 1 : 0
134 
135  Behavior on opacity {
136  UbuntuNumberAnimation {}
137  }
138 
139  onClicked: pinentryField.backspace()
140  }
141  }
142 
143  Label {
144  objectName: "retryLabel"
145  fontSize: "x-small"
146  color: "#f3f3e7"
147  anchors.horizontalCenter: parent.horizontalCenter
148  text: root.retryText || " "
149  }
150  }
151 
152  ThinDivider {
153  anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
154  }
155 
156  Grid {
157  id: numbersGrid
158  anchors { horizontalCenter: parent.horizontalCenter }
159  columns: 3
160 
161  property int buttonHeight: units.gu(8)
162  property int buttonWidth: units.gu(12)
163 
164  Repeater {
165  model: 9
166 
167  PinPadButton {
168  objectName: "pinPadButton" + text
169  text: index + 1
170  height: numbersGrid.buttonHeight
171  width: numbersGrid.buttonWidth
172  enabled: root.entryEnabled && (root.maxPinLength == -1 ||
173  pinentryField.text.length < root.maxPinLength ||
174  pinentryField.incorrectOverride)
175 
176  onClicked: {
177  pinentryField.appendNumber(index + 1)
178  }
179  }
180  }
181  Item {
182  height: numbersGrid.buttonHeight
183  width: numbersGrid.buttonWidth
184  }
185  PinPadButton {
186  text: "0"
187  height: numbersGrid.buttonHeight
188  width: numbersGrid.buttonWidth
189  enabled: root.entryEnabled && (root.maxPinLength == -1 ||
190  pinentryField.text.length < root.maxPinLength ||
191  pinentryField.incorrectOverride)
192 
193  onClicked: {
194  pinentryField.appendNumber(0)
195  }
196  }
197  Item {
198  height: numbersGrid.buttonHeight
199  width: numbersGrid.buttonWidth
200  }
201  PinPadButton {
202  iconName: "close"
203  height: units.gu(5) // visual spec has this row a little closer in
204  width: numbersGrid.buttonWidth
205 
206  onClicked: root.cancel()
207  visible: root.showCancelButton
208  }
209  Item {
210  height: units.gu(5)
211  width: numbersGrid.buttonWidth
212  }
213  PinPadButton {
214  iconName: "tick"
215  objectName: "confirmButton"
216  height: units.gu(5)
217  width: numbersGrid.buttonWidth
218  enabled: root.enabled && pinentryField.text.length >= root.minPinLength
219  visible: root.minPinLength == -1 || root.minPinLength !== root.maxPinLength
220 
221  onClicked: root.entered(pinentryField.text)
222  }
223  }
224  WrongPasswordAnimation {
225  id: wrongPasswordAnimation
226  objectName: "wrongPasswordAnimation"
227  target: shakeContainer
228  }
229 }