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