18 import Ubuntu.Components 0.1
19 import LightDM 0.1 as LightDM
20 import "../Components"
25 property alias userList: userList
26 property alias model: userList.model
27 property alias currentIndex: userList.currentIndex
29 readonly
property int numAboveBelow: 4
30 readonly
property int cellHeight: units.gu(5)
31 readonly
property int highlightedHeight: units.gu(10)
32 readonly
property int moveDuration: 200
33 property bool wasPrompted:
false
35 signal selected(
int uid)
36 signal unlocked(
int uid)
38 Keys.onEscapePressed: root.resetAuthentication()
45 verticalCenter: parent.verticalCenter
47 height: root.highlightedHeight
48 color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
49 border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
50 border.width: units.dp(1)
57 objectName:
"userList"
61 preferredHighlightBegin: userList.height / 2 - root.highlightedHeight / 2
62 preferredHighlightEnd: userList.height / 2 - root.highlightedHeight / 2
63 highlightRangeMode: ListView.StrictlyEnforceRange
64 highlightMoveDuration: root.moveDuration
65 flickDeceleration: 10000
67 readonly
property bool movingInternally: moveTimer.running || userList.moving
69 onCurrentIndexChanged: {
70 if (LightDM.Greeter.authenticationUser != userList.model.data(currentIndex, LightDM.UserRoles.NameRole)) {
71 root.resetAuthentication();
75 onMovingInternallyChanged: {
77 if (!movingInternally) {
78 root.selected(userList.currentIndex);
84 height: root.cellHeight
86 readonly
property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex)
87 readonly
property int belowOffset: root.highlightedHeight - root.cellHeight
94 var highlightDist = 0;
95 var realY = y - userList.contentY;
98 if (realY + height <= highlightItem.y)
99 highlightDist = realY + height - highlightItem.y;
100 else if (realY >= highlightItem.y + root.highlightedHeight)
101 highlightDist = realY - highlightItem.y - root.highlightedHeight;
104 return 1 - Math.min(1, (Math.abs(highlightDist) + root.cellHeight) / ((root.numAboveBelow + 1) * root.cellHeight))
108 objectName:
"username" + index
112 leftMargin: units.gu(2)
114 rightMargin: units.gu(2)
117 topMargin: units.gu(1) + (parent.belowHighlight ? parent.belowOffset : 0)
121 elide: Text.ElideRight
123 Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
132 topMargin: parent.belowHighlight ? parent.belowOffset : 0
134 height: parent.height
135 enabled: userList.currentIndex !== index
138 userList.currentIndex = index;
141 Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
151 interval: root.moveDuration
157 objectName:
"infoLabel"
159 bottom: passwordInput.top
161 topMargin: units.gu(1)
162 bottomMargin: units.gu(1)
163 leftMargin: units.gu(2)
164 rightMargin: units.gu(1)
168 width: root.width - anchors.leftMargin - anchors.rightMargin
170 textFormat: Text.StyledText
173 opacity: (userList.movingInternally || text ==
"") ? 0 : 1
174 Behavior on opacity {
175 NumberAnimation { duration: 100 }
181 objectName:
"passwordInput"
183 bottom: highlightItem.bottom
184 horizontalCenter: parent.horizontalCenter
187 height: units.gu(4.5)
188 width: parent.width - anchors.margins * 2
189 opacity: userList.movingInternally ? 0 : 1
191 Behavior on opacity {
192 NumberAnimation { duration: 100 }
196 if (text ==
"")
return;
201 LightDM.Greeter.respond(text);
203 Keys.onEscapePressed: root.resetAuthentication()
208 rightMargin: units.gu(2)
209 verticalCenter: parent.verticalCenter
211 visible: LightDM.Greeter.promptless
212 source:
"graphics/icon_arrow.png"
215 WrongPasswordAnimation {
216 id: wrongPasswordAnimation
217 target: passwordInput
221 target: Qt.inputMethod
223 if (!Qt.inputMethod.visible) {
224 passwordInput.focus =
false;
232 anchors.fill: passwordInput
233 enabled: LightDM.Greeter.promptless
235 if (LightDM.Greeter.authenticated)
236 root.unlocked(userList.currentIndex);
238 root.resetAuthentication();
242 function resetAuthentication() {
243 if (!userList.currentItem) {
247 passwordInput.placeholderText =
"";
248 passwordInput.text =
"";
249 passwordInput.focus =
false;
250 passwordInput.enabled =
true;
251 root.wasPrompted =
false;
252 LightDM.Greeter.authenticate(userList.model.data(currentIndex, LightDM.UserRoles.NameRole));
256 target: LightDM.Greeter
260 text = text.replace(/&/g,
"&").replace(/</g,
"<").replace(/>/g,
">").replace(/\n/g,
"<br>");
262 text =
"<font color=\"#df382c\">" + text +
"</font>"
263 if (infoLabel.text ==
"")
264 infoLabel.text = text;
266 infoLabel.text = infoLabel.text +
"<br>" + text;
270 passwordInput.text =
"";
271 passwordInput.placeholderText = text;
272 passwordInput.enabled =
true;
273 passwordInput.echoMode = isSecret ? TextInput.Password : TextInput.Normal;
274 if (root.wasPrompted)
275 passwordInput.focus =
true;
276 root.wasPrompted =
true;
279 onAuthenticationComplete: {
280 if (LightDM.Greeter.promptless) {
281 passwordInput.placeholderText = LightDM.Greeter.authenticated ?
"Tap to unlock" :
"Retry";
284 if (LightDM.Greeter.authenticated) {
285 root.unlocked(userList.currentIndex);
287 wrongPasswordAnimation.start();
288 root.resetAuthentication();
289 passwordInput.focus =
true;
291 passwordInput.text =
"";
294 onRequestAuthenticationUser: {
296 for (var i = 0; i < userList.model.count; i++) {
297 if (user == userList.model.data(i, LightDM.UserRoles.NameRole)) {
299 userList.currentIndex = i;