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