205 lines
7.3 KiB
QML
205 lines
7.3 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Effects
|
|
|
|
Rectangle {
|
|
id: root
|
|
width: 1920
|
|
height: 1080
|
|
color: "#223638"
|
|
property date now: new Date()
|
|
property bool busy: false
|
|
property string message: ""
|
|
readonly property color cream: "#eee8dd"
|
|
readonly property color muted: "#bcb5ab"
|
|
readonly property color red: "#bc3b3b"
|
|
readonly property color dark: "#1c1717"
|
|
|
|
FontLoader { id: face; source: "font.ttf" }
|
|
Timer { interval: 1000; running: true; repeat: true; onTriggered: root.now = new Date() }
|
|
|
|
function login() {
|
|
if (busy) return
|
|
if (!username.text.trim() || session.count === 0) {
|
|
message = "Enter a username and select a session."
|
|
return
|
|
}
|
|
message = ""
|
|
busy = true
|
|
sddm.login(username.text.trim(), password.text, session.currentIndex)
|
|
}
|
|
|
|
Connections {
|
|
target: sddm
|
|
function onLoginFailed() {
|
|
root.busy = false
|
|
root.message = "Login failed. Please try again."
|
|
password.clear()
|
|
password.forceActiveFocus()
|
|
}
|
|
function onLoginSucceeded() { root.message = "Welcome back!" }
|
|
function onInformationMessage(message) { root.message = message }
|
|
}
|
|
|
|
Image {
|
|
id: wallpaper
|
|
anchors.fill: parent
|
|
source: "background.jpg"
|
|
fillMode: Image.PreserveAspectCrop
|
|
visible: false
|
|
}
|
|
MultiEffect {
|
|
anchors.fill: parent
|
|
source: wallpaper
|
|
blurEnabled: true
|
|
blurMax: 64
|
|
blur: 1.0
|
|
brightness: -0.2
|
|
}
|
|
Rectangle { anchors.fill: parent; color: "#30223638" }
|
|
|
|
component Card: Rectangle {
|
|
radius: 25
|
|
color: "#991c2827"
|
|
}
|
|
component LabelText: Text {
|
|
color: root.cream
|
|
font.family: face.name
|
|
font.pixelSize: 20
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
component Action: Button {
|
|
id: action
|
|
property color fill: "#cda67d"
|
|
font.family: face.name
|
|
font.pixelSize: 18
|
|
background: Rectangle {
|
|
radius: 20
|
|
color: action.down ? Qt.darker(action.fill, 1.2) : action.fill
|
|
border.width: action.activeFocus ? 2 : 0
|
|
border.color: root.cream
|
|
opacity: action.enabled ? 1 : 0.5
|
|
}
|
|
contentItem: Text {
|
|
text: action.text
|
|
font: action.font
|
|
color: root.dark
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
|
|
Item {
|
|
width: 760
|
|
height: 650
|
|
anchors.centerIn: parent
|
|
scale: Math.min(1, root.width / 900, root.height / 780)
|
|
|
|
Card {
|
|
width: 360; height: 380
|
|
LabelText { x: 20; y: 32; width: 320; text: "NixOS · " + sddm.hostName; color: root.muted }
|
|
LabelText { x: 20; y: 76; width: 320; text: "Log in"; font.pixelSize: 56 }
|
|
|
|
Rectangle {
|
|
x: 20; y: 185; width: 320; height: 70; radius: 20; color: root.red
|
|
LabelText { x: 18; y: 6; text: "Username"; color: root.dark; font.pixelSize: 14 }
|
|
TextField {
|
|
id: username
|
|
x: 10; y: 25; width: 300; height: 40
|
|
text: userModel.lastUser
|
|
color: root.dark
|
|
font.family: face.name; font.pixelSize: 28
|
|
selectByMouse: true
|
|
enabled: !root.busy
|
|
background: Item {}
|
|
onAccepted: password.forceActiveFocus()
|
|
KeyNavigation.tab: password
|
|
}
|
|
}
|
|
Rectangle {
|
|
x: 20; y: 275; width: 320; height: 70; radius: 20; color: root.red
|
|
LabelText { x: 18; y: 6; text: "Password"; color: root.dark; font.pixelSize: 14 }
|
|
TextField {
|
|
id: password
|
|
x: 10; y: 25; width: 300; height: 40
|
|
color: root.dark
|
|
font.family: face.name; font.pixelSize: 28
|
|
echoMode: TextInput.Password
|
|
selectByMouse: true
|
|
enabled: !root.busy
|
|
background: Item {}
|
|
onAccepted: root.login()
|
|
KeyNavigation.tab: session
|
|
KeyNavigation.backtab: username
|
|
}
|
|
}
|
|
}
|
|
|
|
Card {
|
|
y: 410; width: 360; height: 160
|
|
LabelText { y: 4; width: 360; height: 116; text: Qt.formatDateTime(root.now, "HH:mm"); font.pixelSize: 96 }
|
|
LabelText { y: 122; width: 360; text: "Welcome back"; color: root.muted; font.pixelSize: 18 }
|
|
}
|
|
|
|
Card {
|
|
x: 400; width: 360; height: 650
|
|
Rectangle {
|
|
x: 116; y: 26; width: 128; height: 128
|
|
radius: 24; color: root.cream; border.width: 4; border.color: root.red
|
|
Image { anchors.fill: parent; anchors.margins: 6; source: "avatar.png"; fillMode: Image.PreserveAspectFit }
|
|
}
|
|
LabelText { y: 168; width: 360; text: Qt.formatDateTime(root.now, "ddd").toUpperCase(); font.pixelSize: 56; font.bold: true }
|
|
LabelText { y: 236; width: 360; text: Qt.formatDateTime(root.now, "dd MMMM, yyyy"); color: root.muted }
|
|
}
|
|
|
|
Card {
|
|
x: 400; y: 330; width: 360; height: 320; color: "#f01c1717"
|
|
LabelText { y: 16; width: 360; text: "Desktop session"; color: root.muted; font.pixelSize: 16 }
|
|
ComboBox {
|
|
id: session
|
|
x: 20; y: 48; width: 320; height: 42
|
|
model: sessionModel
|
|
textRole: "name"
|
|
currentIndex: Math.max(0, sessionModel.lastIndex)
|
|
enabled: !root.busy
|
|
font.family: face.name; font.pixelSize: 18
|
|
palette.button: "#332a29"
|
|
palette.buttonText: root.cream
|
|
palette.text: root.cream
|
|
palette.base: root.dark
|
|
palette.highlight: root.red
|
|
KeyNavigation.tab: loginButton
|
|
KeyNavigation.backtab: password
|
|
}
|
|
Row {
|
|
x: 20; y: 112; spacing: 20
|
|
Action { width: 150; height: 75; text: "Restart"; enabled: sddm.canReboot && !root.busy; onClicked: sddm.reboot() }
|
|
Action { width: 150; height: 75; text: "Power off"; enabled: sddm.canPowerOff && !root.busy; onClicked: sddm.powerOff() }
|
|
}
|
|
Action {
|
|
id: loginButton
|
|
x: 20; y: 205; width: 320; height: 70
|
|
fill: root.red
|
|
text: root.busy ? "Logging in…" : "Log in"
|
|
font.pixelSize: 30
|
|
enabled: !root.busy && session.count > 0
|
|
onClicked: root.login()
|
|
KeyNavigation.tab: username
|
|
KeyNavigation.backtab: session
|
|
}
|
|
LabelText {
|
|
x: 12; y: 282; width: 336; height: 32
|
|
text: root.message
|
|
font.pixelSize: 12
|
|
color: root.cream
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
if (username.text) password.forceActiveFocus()
|
|
else username.forceActiveFocus()
|
|
}
|
|
}
|