feat(assets): NexusOS asset + theme rebrand
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Executable
+397
@@ -0,0 +1,397 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user