Unity 8
 All Classes Functions Properties
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(3.5)
26 
27  property alias placeholderText: pinentryField.placeholderText
28  property alias wrongPlaceholderText: pinentryField.wrongPlaceholderText
29  property int padWidth: units.gu(34)
30  property int padHeight: units.gu(28)
31  property int minPinLength: -1
32  property int maxPinLength: -1
33 
34  signal entered(string passphrase)
35  signal cancel()
36 
37  property bool entryEnabled: true
38 
39  function clear(playAnimation) {
40  pinentryField.text = "";
41  if (playAnimation) {
42  wrongPasswordAnimation.start();
43  }
44  }
45 
46  QtObject {
47  id: priv
48  property bool autoConfirm: root.minPinLength == root.maxPinLength && root.minPinLength != -1
49  }
50 
51  UbuntuShape {
52  id: pinentryField
53  objectName: "pinentryField"
54  anchors.horizontalCenter: parent.horizontalCenter
55  color: "#55000000"
56  width:root.padWidth
57  height: units.gu(5)
58  radius: "medium"
59  property string text: ""
60  property string placeholderText: ""
61  property string wrongPlaceholderText: ""
62 
63  function appendChar(character) {
64  if (root.maxPinLength == -1 || pinentryField.text.length < root.maxPinLength) {
65  pinentryField.text = pinentryField.text + character;
66  }
67  }
68 
69  onTextChanged: {
70  pinentryFieldLabel.text = "";
71  for (var i = 0; i < text.length; ++i) {
72  pinentryFieldLabel.text += "•";
73  }
74  if (priv.autoConfirm && text.length === root.maxPinLength) {
75  root.entered(text);
76  }
77  }
78 
79  Label {
80  id: pinentryFieldLabel
81  anchors.centerIn: parent
82  width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2
83  elide: Text.ElideMiddle
84  horizontalAlignment: Text.AlignHCenter
85  font.pixelSize: units.dp(44)
86  color: "#f3f3e7"
87  opacity: 0.6
88  }
89  Label {
90  id: pinentryFieldPlaceHolder
91  objectName: "pinentryFieldPlaceHolder"
92  anchors.centerIn: parent
93  color: "#f3f3e7"
94  opacity: 0.6
95  text: wrongPasswordAnimation.running ? parent.wrongPlaceholderText : parent.placeholderText
96  visible: pinentryFieldLabel.text.length == 0
97  }
98 
99  Icon {
100  id: backspaceIcon
101  objectName: "backspaceIcon"
102  anchors {
103  top: parent.top
104  topMargin: units.gu(1)
105  right: parent.right
106  rightMargin: units.gu(2)
107  bottom: parent.bottom
108  bottomMargin: units.gu(1)
109  }
110  visible: !priv.autoConfirm
111  width: height
112  name: "erase"
113  color: "#f3f3e7"
114  opacity: 0.6
115  MouseArea {
116  anchors.fill: parent
117  onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
118  }
119  }
120  }
121 
122  UbuntuShape {
123  anchors {
124  left: parent.left
125  right: parent.right
126  margins: (parent.width - root.padWidth) / 2
127  }
128  height: root.padHeight
129  color: "#55000000"
130  radius: "medium"
131 
132  ThinDivider {
133  anchors {
134  left: parent.left
135  right: parent.right
136  top: parent.top
137  topMargin: root.padHeight / 4
138  }
139  }
140  ThinDivider {
141  anchors {
142  left: parent.left
143  right: parent.right
144  verticalCenter: parent.verticalCenter
145  }
146  }
147  ThinDivider {
148  anchors {
149  left: parent.left
150  right: parent.right
151  bottom: parent.bottom
152  bottomMargin: root.padHeight / 4
153  }
154  }
155 
156  ThinDivider {
157  anchors.centerIn: parent
158  anchors.horizontalCenterOffset: -root.padWidth / 6
159  width: root.padHeight
160  rotation: -90
161  }
162  ThinDivider {
163  anchors.centerIn: parent
164  anchors.horizontalCenterOffset: root.padWidth / 6
165  width: root.padHeight
166  rotation: -90
167  }
168 
169  Grid {
170  anchors {
171  left: parent.left
172  right: parent.right
173  margins: (parent.width - root.padWidth) / 2
174  }
175 
176  columns: 3
177 
178  Repeater {
179  model: 9
180 
181  PinPadButton {
182  objectName: "pinPadButton" + (index + 1)
183  width: root.padWidth / 3
184  height: root.padHeight / 4
185  text: index + 1
186  enabled: entryEnabled
187 
188  onClicked: {
189  pinentryField.appendChar(text);
190  }
191  }
192  }
193 
194  PinPadButton {
195  objectName: "pinPadButtonBack"
196  width: root.padWidth / 3
197  height: root.padHeight / 4
198  subText: i18n.tr("CANCEL")
199  onClicked: root.cancel();
200  }
201 
202  PinPadButton {
203  objectName: "pinPadButton0"
204  width: root.padWidth / 3
205  height: root.padHeight / 4
206  text: "0"
207  onClicked: pinentryField.appendChar(text);
208  enabled: entryEnabled
209  }
210 
211  PinPadButton {
212  objectName: "pinPadButtonErase"
213  width: root.padWidth / 3
214  height: root.padHeight / 4
215  iconName: priv.autoConfirm ? "erase" : ""
216  subText: priv.autoConfirm ? "" : i18n.tr("DONE")
217  onClicked: {
218  if (priv.autoConfirm) {
219  pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
220  } else {
221  root.entered(pinentryField.text);
222  }
223  }
224  enabled: priv.autoConfirm ? entryEnabled : pinentryField.text.length >= root.minPinLength
225  }
226  }
227  }
228 
229  WrongPasswordAnimation {
230  id: wrongPasswordAnimation
231  objectName: "wrongPasswordAnimation"
232  target: pinentryField
233  }
234 }