parch-sddm/parch/components/UserPanel.qml

324 lines
8.6 KiB
QML
Raw Permalink Normal View History

2023-08-03 15:22:52 +03:30
import QtGraphicalEffects 1.12
import QtQml.Models 2.12
import QtQuick 2.12
import QtQuick.Controls 2.12
Column {
property var username: usernameField.text
spacing: 30
Component.onCompleted: userPicture.source = userWrapper.items.get(userList.currentIndex).model.icon
DelegateModel {
id: userWrapper
model: userModel
delegate: ItemDelegate {
id: userEntry
height: inputHeight
width: parent.width
highlighted: userList.currentIndex == index
states: [
State {
name: "hovered"
when: userEntry.hovered
PropertyChanges {
target: userEntryBg
color: highlighted ? Qt.darker(config.PopupHighlight, 1.2) : Qt.darker(config.PopupBackground, 1.2)
}
}
]
MouseArea {
anchors.fill: parent
onClicked: {
userList.currentIndex = index;
usernameField.text = userWrapper.items.get(index).model.name;
userPicture.source = userWrapper.items.get(index).model.icon;
userPopup.close();
}
}
contentItem: Text {
renderType: Text.NativeRendering
font.family: config.Font
font.pointSize: config.FontSize
font.bold: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: highlighted ? config.PopupHighlightText : config.PopupHighlight
text: name
}
background: Rectangle {
id: userEntryBg
color: highlighted ? config.PopupHighlight : config.PopupBackground
radius: config.Radius
}
transitions: Transition {
PropertyAnimation {
property: "color"
duration: 150
}
}
}
}
Popup {
id: userPopup
width: inputWidth
padding: 15
background: Rectangle {
radius: config.Radius * 1.8
color: config.PopupBackground
}
contentItem: ListView {
id: userList
implicitHeight: contentHeight
spacing: 8
model: userWrapper
currentIndex: userModel.lastIndex
clip: true
}
enter: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 0
to: 1
duration: 400
easing.type: Easing.OutExpo
}
NumberAnimation {
property: "y"
from: (inputWidth / 3) - userPopup.padding - (inputHeight * userList.count * 0.5) - (userList.spacing * (userList.count - 1) * 0.5) + (inputWidth * 0.1)
to: (inputWidth / 3) - userPopup.padding - (inputHeight * userList.count * 0.5) - (userList.spacing * (userList.count - 1) * 0.5)
duration: 500
easing.type: Easing.OutExpo
}
}
}
exit: Transition {
NumberAnimation {
property: "opacity"
from: 1
to: 0
duration: 300
easing.type: Easing.OutExpo
}
}
}
Item {
width: inputWidth
implicitHeight: pictureBorder.height
Rectangle {
id: pictureBorder
anchors.centerIn: userPicture
height: inputWidth / 1.5 + (border.width * 2)
width: inputWidth / 1.5 + (border.width * 2)
radius: height / 2
border.width: config.UAPBorderWidth
border.color: config.UAPBorderColor
color: config.UAPColor
states: [
State {
name: "pressed"
PropertyChanges {
target: pictureBorder
border.color: Qt.darker(config.UAPBorderColor, 1.2)
color: Qt.darker(config.UAPColor, 1.2)
}
},
State {
name: "hovered"
PropertyChanges {
target: pictureBorder
border.color: Qt.darker(config.UAPBorderColor, 1.4)
color: Qt.darker(config.UAPColor, 1.4)
}
},
State {
name: "unhovered"
PropertyChanges {
target: pictureBorder
border.color: config.UAPBorderColor
color: config.UAPColor
}
}
]
MouseArea {
id: roundMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: userPopup.open()
onHoveredChanged: {
if (containsMouse)
pictureBorder.state = "hovered";
else
pictureBorder.state = "unhovered";
}
onPressedChanged: {
if (containsPress)
pictureBorder.state = "pressed";
else if (containsMouse)
pictureBorder.state = "hovered";
else
pictureBorder.state = "unhovered";
}
}
transitions: Transition {
PropertyAnimation {
properties: "border.color, color"
duration: 150
}
}
}
Image {
id: userPicture
source: ""
height: inputWidth / 1.5
width: inputWidth / 1.5
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectCrop
layer.enabled: true
Rectangle {
id: mask
anchors.fill: parent
radius: inputWidth / 3
visible: false
}
layer.effect: OpacityMask {
maskSource: mask
}
}
Popup {
id: incorrectPopup
height: incorrectText.paintedHeight * 2
width: inputWidth
y: (pictureBorder.height - height) / 2
onOpened: incorrectTimer.start()
Timer {
id: incorrectTimer
interval: 3000
onTriggered: incorrectPopup.close()
}
background: Rectangle {
radius: config.Radius
color: config.PopupBackground
}
contentItem: Text {
id: incorrectText
renderType: Text.NativeRendering
font.family: config.Font
font.pointSize: config.FontSize
font.bold: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: config.PopupHighlight
text: "Incorrect username\nor password!"
}
enter: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 0
to: 1
duration: 400
easing.type: Easing.OutExpo
}
NumberAnimation {
property: "x"
from: incorrectPopup.x - (inputWidth * 0.1)
to: incorrectPopup.x
duration: 500
easing.type: Easing.OutElastic
}
}
}
exit: Transition {
NumberAnimation {
property: "opacity"
from: 1
to: 0
duration: 300
easing.type: Easing.OutExpo
}
}
}
}
UserFieldPanel {
id: usernameField
height: inputHeight
width: inputWidth
}
Connections {
function onLoginSucceeded() {
}
function onLoginFailed() {
incorrectPopup.open();
}
target: sddm
}
}