166 lines
6.5 KiB
QML
166 lines
6.5 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import SddmComponents
|
|
|
|
Item {
|
|
id: selector
|
|
|
|
signal openUserList
|
|
signal closeUserList
|
|
signal userChanged(userIndex: int, username: string, userRealName: string, userIcon: string, needsPassword: bool)
|
|
|
|
property bool listUsers: false
|
|
property string orientation: ""
|
|
property bool isDragging: false
|
|
|
|
function prevUser() {
|
|
userList.decrementCurrentIndex();
|
|
}
|
|
function nextUser() {
|
|
userList.incrementCurrentIndex();
|
|
}
|
|
|
|
ListView {
|
|
id: userList
|
|
anchors.fill: parent
|
|
orientation: selector.orientation === "horizontal" ? ListView.Horizontal : ListView.Vertical
|
|
spacing: 10
|
|
interactive: false
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
|
|
// Center the active avatar
|
|
preferredHighlightBegin: selector.orientation === "horizontal" ? (width - Config.avatarActiveSize) / 2 : (height - Config.avatarActiveSize) / 2
|
|
preferredHighlightEnd: preferredHighlightBegin
|
|
highlightRangeMode: ListView.StrictlyEnforceRange
|
|
// Padding for centering
|
|
leftMargin: selector.orientation === "horizontal" ? preferredHighlightBegin : 0
|
|
rightMargin: leftMargin
|
|
topMargin: selector.orientation === "horizontal" ? 0 : preferredHighlightBegin
|
|
bottomMargin: topMargin
|
|
|
|
// Animation properties
|
|
highlightMoveDuration: 200
|
|
highlightResizeDuration: 200
|
|
highlightMoveVelocity: -1
|
|
highlightFollowsCurrentItem: true
|
|
|
|
model: userModel
|
|
currentIndex: userModel.lastIndex
|
|
onCurrentIndexChanged: {
|
|
var username = userModel.data(userModel.index(currentIndex, 0), 257);
|
|
var userRealName = userModel.data(userModel.index(currentIndex, 0), 258);
|
|
var userIcon = userModel.data(userModel.index(currentIndex, 0), 260);
|
|
var needsPasswd = userModel.data(userModel.index(currentIndex, 0), 261);
|
|
|
|
sddm.currentUser = username;
|
|
selector.userChanged(currentIndex, username, userRealName, userIcon, needsPasswd);
|
|
}
|
|
|
|
delegate: Rectangle {
|
|
width: index === userList.currentIndex ? Config.avatarActiveSize : Config.avatarInactiveSize
|
|
height: index === userList.currentIndex ? Config.avatarActiveSize : Config.avatarInactiveSize
|
|
anchors {
|
|
verticalCenter: selector.orientation === "horizontal" ? parent.verticalCenter : undefined
|
|
horizontalCenter: selector.orientation === "horizontal" ? undefined : parent.horizontalCenter
|
|
}
|
|
color: "transparent"
|
|
visible: selector.listUsers || index === userList.currentIndex
|
|
|
|
Behavior on width {
|
|
enabled: Config.enableAnimations
|
|
NumberAnimation {
|
|
duration: 200
|
|
easing.type: Easing.OutQuad
|
|
}
|
|
}
|
|
Behavior on height {
|
|
enabled: Config.enableAnimations
|
|
NumberAnimation {
|
|
duration: 200
|
|
easing.type: Easing.OutQuad
|
|
}
|
|
}
|
|
opacity: selector.listUsers || index === userList.currentIndex ? 1.0 : 0.0
|
|
Behavior on opacity {
|
|
enabled: Config.enableAnimations
|
|
NumberAnimation {
|
|
duration: 200
|
|
}
|
|
}
|
|
|
|
Avatar {
|
|
width: parent.width
|
|
height: parent.height
|
|
source: model.icon
|
|
active: index === userList.currentIndex
|
|
opacity: active ? 1.0 : Config.avatarInactiveOpacity
|
|
enabled: userModel.rowCount() > 1 // No need to open the selector if there's only one user
|
|
tooltipText: active && selector.listUsers ? "Close user selection" : (active && !listUsers ? "Select user" : `Select user ${model.name}`)
|
|
showTooltip: selector.focus && !listUsers && active
|
|
|
|
Behavior on opacity {
|
|
enabled: Config.enableAnimations
|
|
NumberAnimation {
|
|
duration: 200
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
if (!selector.listUsers) {
|
|
// Open selector
|
|
selector.openUserList();
|
|
selector.focus = true;
|
|
userList.model.reset();
|
|
} else {
|
|
// Collapse the list if the selected user gets another click
|
|
if (index === userList.currentIndex) {
|
|
selector.closeUserList();
|
|
selector.focus = false;
|
|
}
|
|
userList.currentIndex = index;
|
|
}
|
|
}
|
|
onClickedOutside: {
|
|
selector.closeUserList();
|
|
selector.focus = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Keys.onPressed: function (event) {
|
|
if (event.key == Qt.Key_Return || event.key == Qt.Key_Enter || event.key === Qt.Key_Space) {
|
|
if (selector.listUsers) {
|
|
selector.closeUserList();
|
|
selector.focus = false;
|
|
} else {
|
|
selector.openUserList();
|
|
selector.focus = true;
|
|
}
|
|
event.accepted = true;
|
|
} else if (event.key == Qt.Key_Escape) {
|
|
selector.closeUserList();
|
|
selector.focus = false;
|
|
event.accepted = true;
|
|
} else if ((selector.orientation === "horizontal" && event.key == Qt.Key_Left) || (selector.orientation === "vertical" && event.key == Qt.Key_Up)) {
|
|
if (userModel.rowCount() > 0) {
|
|
userList.currentIndex = (userList.currentIndex + userModel.rowCount() - 1) % userModel.rowCount();
|
|
}
|
|
selector.focus = true;
|
|
event.accepted = true;
|
|
} else if ((selector.orientation === "horizontal" && event.key == Qt.Key_Right) || (selector.orientation === "vertical" && event.key == Qt.Key_Down)) {
|
|
if (userModel.rowCount() > 0) {
|
|
userList.currentIndex = (userList.currentIndex + userModel.rowCount() + 1) % userModel.rowCount();
|
|
}
|
|
selector.focus = true;
|
|
event.accepted = true;
|
|
} else if (event.key === Qt.Key_CapsLock) {
|
|
root.capsLockOn = !root.capsLockOn;
|
|
event.accepted = true;
|
|
} else {
|
|
// Do not steal other keys
|
|
event.accepted = false;
|
|
}
|
|
}
|
|
}
|