Files
2026-07-11 07:25:15 -05:00

398 lines
13 KiB
QML
Executable File

import QtQuick 2.0
import SddmComponents 2.0
Rectangle {
id: root
width: 1920
height: 1200
readonly property color accentColor: "#8cc63f" // brand_green
readonly property color bgDark: "#1e1526" // base_bg
readonly property color textPrimary: "#f2f2f2" // text_primary
readonly property color textMuted: "#a8a8a8" // text_secondary
readonly property color fieldBg: "#1f2225" // surface_bg
readonly property color fieldBorder: "#4d3461" // menu_border (purple tint)
readonly property color errorColor: "#da4453" // error_color
property int sessionIndex: sessionModel.lastIndex
Connections {
target: sddm
onLoginFailed: {
errorMsg.text = "Login failed — check your credentials."
passwordInput.text = ""
passwordInput.focus = true
shakeAnim.start()
}
onLoginSucceeded: {
errorMsg.text = ""
}
}
Image {
anchors.fill: parent
source: "assets/background.svg"
fillMode: Image.PreserveAspectCrop
smooth: true
asynchronous: false
}
Rectangle {
anchors.fill: parent
color: "#000000"
opacity: 0.25
}
Item {
id: logoArea
width: 120
height: 120
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: parent.height * 0.10
Rectangle {
anchors.centerIn: parent
width: parent.width * 1.6
height: parent.height * 1.6
radius: width / 2
color: accentColor
opacity: 0.06
}
Image {
id: logo
anchors.fill: parent
source: "assets/logo.png"
sourceSize: Qt.size(200, 200)
smooth: true
}
}
Text {
id: brandLabel
text: "NexusOS"
color: textPrimary
font.family: "Sans"
font.pixelSize: 28
font.letterSpacing: 6
font.weight: Font.Light
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: logoArea.bottom
anchors.topMargin: 16
}
Rectangle {
id: loginBox
width: 360
height: loginColumn.height + 60
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: brandLabel.bottom
anchors.topMargin: parent.height * 0.08
color: Qt.rgba(15/255, 22/255, 38/255, 0.75)
radius: 12
border.color: fieldBorder
border.width: 1
SequentialAnimation {
id: shakeAnim
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x - 10; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x + 10; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x - 6; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x + 6; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x; duration: 40 }
}
Column {
id: loginColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 30
spacing: 14
Rectangle {
id: sessionBox
width: parent.width
height: 40
color: fieldBg
radius: 6
border.color: sessionDropdown.visible ? accentColor : fieldBorder
border.width: 1
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14
anchors.right: sessionArrow.left
anchors.rightMargin: 8
text: sessionModel.data(sessionModel.index(sessionIndex, 0), Qt.DisplayRole) || "Session"
color: textPrimary
font.pixelSize: 13
elide: Text.ElideRight
}
Text {
id: sessionArrow
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 14
text: sessionDropdown.visible ? "▲" : "▼"
color: textMuted
font.pixelSize: 10
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!sessionDropdown.visible) {
var pos = sessionBox.mapToItem(root, 0, sessionBox.height)
sessionDropdown.x = pos.x
sessionDropdown.y = pos.y + 2
sessionDropdown.width = sessionBox.width
}
sessionDropdown.visible = !sessionDropdown.visible
}
}
}
Rectangle {
width: parent.width
height: 44
color: fieldBg
radius: 6
border.color: usernameInput.activeFocus ? accentColor : fieldBorder
border.width: 1
TextInput {
id: usernameInput
anchors.fill: parent
anchors.leftMargin: 14
anchors.rightMargin: 14
verticalAlignment: TextInput.AlignVCenter
color: textPrimary
font.pixelSize: 14
clip: true
text: userModel.lastUser
Keys.onTabPressed: passwordInput.forceActiveFocus()
Keys.onReturnPressed: sddm.login(usernameInput.text, passwordInput.text, sessionIndex)
}
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14
text: "Username"
color: textMuted
font.pixelSize: 14
visible: usernameInput.text.length === 0 && !usernameInput.activeFocus
}
}
Rectangle {
width: parent.width
height: 44
color: fieldBg
radius: 6
border.color: passwordInput.activeFocus ? accentColor : fieldBorder
border.width: 1
TextInput {
id: passwordInput
anchors.fill: parent
anchors.leftMargin: 14
anchors.rightMargin: 14
verticalAlignment: TextInput.AlignVCenter
color: textPrimary
font.pixelSize: 14
echoMode: TextInput.Password
clip: true
focus: true
Keys.onReturnPressed: sddm.login(usernameInput.text, passwordInput.text, sessionIndex)
}
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14
text: "Password"
color: textMuted
font.pixelSize: 14
visible: passwordInput.text.length === 0 && !passwordInput.activeFocus
}
}
Text {
id: errorMsg
width: parent.width
text: ""
color: errorColor
font.pixelSize: 12
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
visible: text !== ""
}
Rectangle {
id: loginButton
width: parent.width
height: 44
radius: 6
color: loginMouse.pressed
? Qt.darker(accentColor, 1.3)
: loginMouse.containsMouse
? Qt.lighter(accentColor, 1.15)
: accentColor
Behavior on color { ColorAnimation { duration: 150 } }
Text {
anchors.centerIn: parent
text: "LOGIN"
color: "#0a0a00" // text_on_accent (dark on lime green)
font.pixelSize: 14
font.letterSpacing: 3
font.weight: Font.DemiBold
}
MouseArea {
id: loginMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: sddm.login(usernameInput.text, passwordInput.text, sessionIndex)
}
}
Item {
width: parent.width
height: 30
Row {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: 30
Text {
text: "⏻ Shutdown"
color: textMuted
font.pixelSize: 12
opacity: shutdownMouse.containsMouse ? 1.0 : 0.7
Behavior on opacity { NumberAnimation { duration: 120 } }
MouseArea {
id: shutdownMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: sddm.powerOff()
}
}
Text {
text: "↻ Reboot"
color: textMuted
font.pixelSize: 12
opacity: rebootMouse.containsMouse ? 1.0 : 0.7
Behavior on opacity { NumberAnimation { duration: 120 } }
MouseArea {
id: rebootMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: sddm.reboot()
}
}
}
}
}
}
Rectangle {
id: sessionDropdown
visible: false
z: 999
color: fieldBg
radius: 6
border.color: fieldBorder
border.width: 1
height: sessionList.contentHeight
clip: true
ListView {
id: sessionList
anchors.fill: parent
model: sessionModel
interactive: false
delegate: Rectangle {
width: sessionList.width
height: 36
color: sessionItemMouse.containsMouse ? Qt.lighter(fieldBg, 1.4) : "transparent"
radius: 4
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14
text: model.name || ""
color: index === sessionIndex ? accentColor : textPrimary
font.pixelSize: 13
}
MouseArea {
id: sessionItemMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
sessionIndex = index
sessionDropdown.visible = false
}
}
}
}
}
Column {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: parent.height * 0.05
spacing: 2
Text {
id: clockText
anchors.horizontalCenter: parent.horizontalCenter
color: textPrimary
font.family: "Sans"
font.pixelSize: 42
font.weight: Font.Thin
}
Text {
id: dateText
anchors.horizontalCenter: parent.horizontalCenter
color: textMuted
font.family: "Sans"
font.pixelSize: 14
font.letterSpacing: 2
}
Timer {
interval: 1000
running: true
repeat: true
triggeredOnStart: true
onTriggered: {
var d = new Date()
clockText.text = Qt.formatTime(d, "hh:mm")
dateText.text = Qt.formatDate(d, "dddd, MMMM d")
}
}
}
}