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