~unity-team/unity8/dash-only

« back to all changes in this revision

Viewing changes to qml/Components/PinLockscreen.qml

  • Committer: Kevin Gunn
  • Date: 2016-10-24 19:51:33 UTC
  • Revision ID: kevin.gunn@canonical.com-20161024195133-61lwdzzdwsnue1mn
shave some more

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.4
18
 
import Ubuntu.Components 1.3
19
 
import Ubuntu.Components.ListItems 1.3
20
 
import "../Components"
21
 
 
22
 
FocusScope {
23
 
    id: root
24
 
    focus: true
25
 
 
26
 
    property string infoText
27
 
    property string retryText
28
 
    property string errorText
29
 
    property int minPinLength: -1
30
 
    property int maxPinLength: -1
31
 
    property bool showCancelButton: true
32
 
    property color foregroundColor: "#000000"
33
 
 
34
 
    readonly property string passphrase: pinentryField.text
35
 
 
36
 
    signal entered(string passphrase)
37
 
    signal cancel()
38
 
 
39
 
    property bool entryEnabled: true
40
 
 
41
 
    function clear(showAnimation) {
42
 
        pinentryField.text = "";
43
 
        if (showAnimation) {
44
 
            pinentryField.incorrectOverride = true;
45
 
            wrongPasswordAnimation.start();
46
 
        }
47
 
    }
48
 
 
49
 
    Keys.onPressed: {
50
 
        if (pinentryField.text.length == root.maxPinLength)
51
 
            return;
52
 
 
53
 
        if (event.key === Qt.Key_Backspace) {
54
 
            pinentryField.backspace();
55
 
        } else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Escape) {
56
 
            closeButton.clicked()
57
 
        } else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
58
 
            confirmButton.clicked()
59
 
        } else {
60
 
            var digit = parseInt(event.text);
61
 
            if (!isNaN(digit) && typeof digit == "number") {
62
 
                pinentryField.appendNumber(digit);
63
 
            }
64
 
        }
65
 
    }
66
 
 
67
 
    Column {
68
 
        anchors {
69
 
            left: parent.left;
70
 
            right: parent.right;
71
 
            verticalCenter: parent.verticalCenter;
72
 
            verticalCenterOffset: Math.max(-units.gu(10), -(root.height - height) / 2) + units.gu(4)
73
 
        }
74
 
        spacing: units.gu(4)
75
 
 
76
 
        Column {
77
 
            id: shakeContainer
78
 
            anchors.horizontalCenter: parent.horizontalCenter
79
 
            width: parent.width
80
 
            spacing: units.gu(1)
81
 
 
82
 
            Label {
83
 
                id: infoField
84
 
                objectName: "infoTextLabel"
85
 
                fontSize: "large"
86
 
                color: root.foregroundColor
87
 
                anchors.horizontalCenter: parent.horizontalCenter
88
 
                text: root.infoText
89
 
            }
90
 
 
91
 
            Item {
92
 
                id: pinContainer
93
 
                anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
94
 
                height: units.gu(4)
95
 
 
96
 
                Row {
97
 
                    id: pinentryField
98
 
                    objectName: "pinentryField"
99
 
                    anchors.horizontalCenter: parent.horizontalCenter
100
 
                    anchors.verticalCenter: parent.verticalCenter
101
 
                    spacing: Math.max(0, Math.min(units.gu(3), (parent.width / root.maxPinLength) - units.gu(3)))
102
 
 
103
 
                    property string text
104
 
                    property bool incorrectOverride: false
105
 
 
106
 
                    Repeater {
107
 
                        model: pinentryField.text.length
108
 
                        delegate: Rectangle {
109
 
                            color: root.foregroundColor
110
 
                            width: Math.min(units.gu(2), (pinContainer.width - pinContainer.height*2 ) / (root.maxPinLength >= 0 ? root.maxPinLength : 16))
111
 
                            height: width
112
 
                            radius: width / 2
113
 
                        }
114
 
                    }
115
 
 
116
 
                    function appendNumber(number) {
117
 
                        if (incorrectOverride) {
118
 
                            incorrectOverride = false;
119
 
                        }
120
 
 
121
 
                        pinentryField.text = pinentryField.text + number
122
 
 
123
 
                        if (root.minPinLength > 0 && root.maxPinLength > 0
124
 
                                && root.minPinLength == root.maxPinLength && pinentryField.text.length == root.minPinLength) {
125
 
                            root.entered(pinentryField.text)
126
 
                        }
127
 
                    }
128
 
 
129
 
                    function backspace() {
130
 
                        pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
131
 
                    }
132
 
                }
133
 
                Label {
134
 
                    id: wrongNoticeLabel
135
 
                    objectName: "wrongNoticeLabel"
136
 
                    fontSize: "x-large"
137
 
                    color: root.foregroundColor
138
 
                    anchors.horizontalCenter: parent.horizontalCenter
139
 
                    horizontalAlignment: Text.AlignHCenter
140
 
                    text: root.errorText
141
 
                    visible: pinentryField.incorrectOverride
142
 
                    scale: Math.min(1, parent.width / width)
143
 
                }
144
 
 
145
 
                AbstractButton {
146
 
                    objectName: "backspaceIcon"
147
 
                    anchors { right: parent.right; top: parent.top; bottom: parent.bottom; margins: -units.gu(1) }
148
 
                    width: height
149
 
                    enabled: root.entryEnabled
150
 
 
151
 
                    Icon {
152
 
                        anchors.fill: parent
153
 
                        anchors.margins: units.gu(1)
154
 
                        name: "erase"
155
 
                        color: root.foregroundColor
156
 
                    }
157
 
 
158
 
                    opacity: (pinentryField.text.length > 0 && !pinentryField.incorrectOverride) ? 1 : 0
159
 
 
160
 
                    Behavior on opacity {
161
 
                        UbuntuNumberAnimation {}
162
 
                    }
163
 
 
164
 
                    onClicked: pinentryField.backspace()
165
 
                }
166
 
            }
167
 
 
168
 
            Label {
169
 
                objectName: "retryLabel"
170
 
                fontSize: "x-small"
171
 
                color: root.foregroundColor
172
 
                anchors.horizontalCenter: parent.horizontalCenter
173
 
                text: root.retryText || " "
174
 
            }
175
 
        }
176
 
 
177
 
        Grid {
178
 
            id: numbersGrid
179
 
            objectName: "numbersGrid"
180
 
            anchors { horizontalCenter: parent.horizontalCenter }
181
 
            columns: 3
182
 
 
183
 
            property int maxWidth: Math.min(units.gu(50), root.width - units.gu(8))
184
 
            property int buttonWidth: maxWidth / 3
185
 
            property int buttonHeight: buttonWidth * 2 / 3
186
 
 
187
 
            Repeater {
188
 
                model: 9
189
 
 
190
 
                PinPadButton {
191
 
                    objectName: "pinPadButton" + text
192
 
                    text: index + 1
193
 
                    height: numbersGrid.buttonHeight
194
 
                    width: numbersGrid.buttonWidth
195
 
                    foregroundColor: root.foregroundColor
196
 
                    enabled: root.entryEnabled && (root.maxPinLength == -1 ||
197
 
                             pinentryField.text.length < root.maxPinLength ||
198
 
                             pinentryField.incorrectOverride)
199
 
 
200
 
                    onClicked: {
201
 
                        pinentryField.appendNumber(index + 1)
202
 
                    }
203
 
                }
204
 
            }
205
 
            Item {
206
 
                height: numbersGrid.buttonHeight
207
 
                width: numbersGrid.buttonWidth
208
 
            }
209
 
            PinPadButton {
210
 
                text: "0"
211
 
                height: numbersGrid.buttonHeight
212
 
                width: numbersGrid.buttonWidth
213
 
                foregroundColor: root.foregroundColor
214
 
                enabled: root.entryEnabled && (root.maxPinLength == -1 ||
215
 
                         pinentryField.text.length < root.maxPinLength ||
216
 
                         pinentryField.incorrectOverride)
217
 
 
218
 
                onClicked: {
219
 
                    pinentryField.appendNumber(0)
220
 
                }
221
 
            }
222
 
            Item {
223
 
                height: numbersGrid.buttonHeight
224
 
                width: numbersGrid.buttonWidth
225
 
            }
226
 
            PinPadButton {
227
 
                id: closeButton
228
 
                iconName: "close"
229
 
                height: units.gu(5) // visual spec has this row a little closer in
230
 
                width: numbersGrid.buttonWidth
231
 
                foregroundColor: root.foregroundColor
232
 
                onClicked: root.cancel()
233
 
                visible: root.showCancelButton
234
 
            }
235
 
            Item {
236
 
                height: units.gu(5)
237
 
                width: numbersGrid.buttonWidth
238
 
            }
239
 
            PinPadButton {
240
 
                id: confirmButton
241
 
                iconName: "tick"
242
 
                objectName: "confirmButton"
243
 
                height: units.gu(5)
244
 
                width: numbersGrid.buttonWidth
245
 
                foregroundColor: root.foregroundColor
246
 
                enabled: root.enabled && pinentryField.text.length >= root.minPinLength
247
 
                visible: root.minPinLength == -1 || root.minPinLength !== root.maxPinLength
248
 
 
249
 
                onClicked: root.entered(pinentryField.text)
250
 
            }
251
 
        }
252
 
        WrongPasswordAnimation {
253
 
            id: wrongPasswordAnimation
254
 
            objectName: "wrongPasswordAnimation"
255
 
            target: shakeContainer
256
 
        }
257
 
    }
258
 
}