on b5edd7d help sign in
unity8/qml/Components/PinLockscreen.qml
227 lines 7.4 kB history raw
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 */
17import QtQuick 2.0
18import Ubuntu.Components 0.1
19import Ubuntu.Components.ListItems 0.1
20import "../Components"
22Column {
23 id: root
24 anchors.top: parent.top
25 anchors.topMargin: units.gu(4)
26 anchors.horizontalCenter: parent.horizontalCenter
27 spacing: units.gu(2)
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
38 signal entered(string passphrase)
39 signal cancel()
41 property bool entryEnabled: true
43 function clear(showAnimation) {
44 pinentryField.text = "";
45 if (showAnimation) {
46 pinentryField.incorrectOverride = true;
47 wrongPasswordAnimation.start();
48 }
49 }
51 Column {
52 id: shakeContainer
53 anchors.horizontalCenter: parent.horizontalCenter
54 width: parent.width
55 spacing: units.gu(1)
57 Label {
58 id: infoField
59 objectName: "infoTextLabel"
60 fontSize: "large"
61 color: "#f3f3e7"
62 anchors.horizontalCenter: parent.horizontalCenter
63 text: root.infoText
64 }
66 Item {
67 id: pinContainer
68 anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
69 height: units.gu(4)
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)))
78 property string text
79 property bool incorrectOverride: false
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 }
91 function appendNumber(number) {
92 if (incorrectOverride) {
93 incorrectOverride = false;
94 }
96 pinentryField.text = pinentryField.text + number
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 }
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 }
120 AbstractButton {
121 objectName: "backspaceIcon"
122 anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
123 width: height
125 Icon {
126 anchors.fill: parent
127 name: "erase"
128 color: "#f3f3e7"
129 }
131 opacity: (pinentryField.text.length && !pinentryField.incorrectOverride) > 0 ? 1 : 0
133 Behavior on opacity {
134 UbuntuNumberAnimation {}
135 }
137 onClicked: pinentryField.backspace()
138 }
139 }
141 Label {
142 objectName: "retryLabel"
143 fontSize: "x-small"
144 color: "#f3f3e7"
145 anchors.horizontalCenter: parent.horizontalCenter
146 text: root.retryText || " "
147 }
148 }
150 ThinDivider {
151 anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
152 }
154 Grid {
155 id: numbersGrid
156 anchors { horizontalCenter: parent.horizontalCenter }
157 columns: 3
159 property int buttonHeight: units.gu(8)
160 property int buttonWidth: units.gu(12)
162 Repeater {
163 model: 9
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)
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)
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
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
219 onClicked: root.entered(pinentryField.text)
220 }
221 }
222 WrongPasswordAnimation {
223 id: wrongPasswordAnimation
224 objectName: "wrongPasswordAnimation"
225 target: shakeContainer
226 }